# -*- coding: utf-8 -*-
# created on 2016/11/30
from mathsolver.functions.shulie.Distinguish import *
from mathsolver.functions.base import *
from sympy.abc import x
from sympy import fraction, log, powsimp, S, expand, cancel, Poly, Tuple
from mathsolver.functions.shulie.Fundamental import *
from mathsolver.functions.shulie.QianNXiangJi import ShuLieGetMul
from mathsolver.functions.shulie.ShuLie_Transform import (ShuLieSnExprNormalization, ShuLieSnEqNormalization,
                                                          ShuLieAnExprNormalization)
from mathsolver.functions.shulie.basic import sl_solve_eqs, sl_solutuons_subs, sl_expr_to_an_value, sl_search_multiple
from mathsolver.functions.mathematica.mathematicaSolve import MathematicaSolve, MathematicaSimplify
from mathsolver.functions.base.base import new_latex


class GetTongXiangGongShi001(BaseFunction):
    """
    求通项公式: a(n) = a(n-1) + d
    1. a(n) = a(n-1) + d
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 2
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """

    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        n_ineqs = args[3]
        a_name = args[4]
        s_name = args[5]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 1
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        try:
            s_ineqs = []
            if n_ineqs:
                for ineq in n_ineqs:
                    left, op, right = ineq
                    expr = left - right
                    max_expr = expr
                    max_expr = max_expr.subs({symbol: max_index})
                    s_ineqs.append([max_expr, op, S.Zero])
                    min_expr = expr
                    min_expr = min_expr.subs({symbol: min_index})
                    s_ineqs.append([min_expr, op, S.Zero])
            s_ineqs.append([fn, S.Zero])
            if len(s_ineqs) > 1:
                solutions = MathematicaSolve().solver(BaseIneqs(s_ineqs), BaseVariable(max_xiang)).output[0].sympify()
                answers = sl_search_multiple(solutions, max_xiang)
                assert len(answers) == 1
                answer = answers[0]
                answer = answer[max_xiang]
            else:
                answer = solve(fn, max_xiang)[0]
        except Exception:
            pass
        eq_right = answer
        assert sl_linear_poly(eq_right, min_xiang)
        a, b = sl_linear_poly_coeffs(eq_right, min_xiang)
        b = ShuLieSnExprNormalization().solver(BasePoly(b), a_name).output[0].sympify()
        assert a == 1
        new_b = str(b)
        assert new_b.find(str(symbol)) < 0
        self.steps.append(["", "依题意，得"])
        tong_xiangs = []
        for item in a1:
            item_value = item[1]
            self.steps.append(
                ["", "数列\\{%s\\}是以%s为首项，%s为公差的等差数列" % (
                    new_latex(min_xiang), new_latex(item_value), new_latex(b))])
            j = sympify('t')
            tong_xiang = b * n + j
            self.steps.append(["", "设%s，则" % (BaseEq([shulie_name[0](n), tong_xiang]).printing())])
            m_eqs = []
            new_a1 = tong_xiang.subs({n: 1})
            new_a1 = ShuLieSnExprNormalization().solver(BasePoly(new_a1), a_name).output[0].sympify()
            m_eqs.append([item_value, new_a1])
            for a1_eq in a1:
                m_eqs.append(a1_eq)
            if aothers:
                for eq in aothers:
                    expr = eq[0] - eq[1]
                    expr = expr.subs({n: 1})
                    m = sl_xiangs(expr)
                    if m:
                        for t in m:
                            new_t = sympify(t)
                            new_t_index = new_t.args[0]
                            new_t_name = new_t.func
                            if str(new_t_name) == str(a_name):
                                new_t_value = tong_xiang.subs({n: new_t_index})
                                expr = expr.subs({new_t: new_t_value})
                            elif str(new_t_name) == str(s_name):
                                new_t_value = new_t_index * new_a1 + new_t_index * (new_t_index - 1) * b / 2
                                expr = expr.subs({new_t: new_t_value})
                    m_eqs.append([expr, S.Zero])
            if len(m_eqs) == 1:
                self.steps.append(["", " %s" % (BaseEq(m_eqs[0]).printing())])
            else:
                self.steps.append(["", " %s" % (BaseEqs(m_eqs).printing())])
            solutions = MathematicaSolve().solver(BaseIneqs(m_eqs), BaseVariable(j)).output[0]
            self.steps.append(["", "解得: %s" % (solutions.printing())])
            tong_xiang = sl_solutuons_subs(solutions, tong_xiang)
            tong_xiangs.extend(tong_xiang)
        if str(shulie_name[0]) == str(a_name):
            self.steps.append(
                ["", "∴ %s" % "或".join(["%s = %s" % (new_latex(a_name(symbol)), new_latex(v)) for v in tong_xiangs])])
            self.output.append(BaseValues(tong_xiangs))
        else:
            assert len(tong_xiangs) == 1
            new_sn = tong_xiangs[0]
            new_sn_1 = new_sn.subs({symbol: symbol - 1})
            new_an = new_sn - new_sn_1
            new_an = new_an.expand().simplify()
            new_a1 = new_an.subs({symbol: 1})
            a1_value = a1[0][1]
            if a1_value - new_a1 == 0:
                self.steps.append(["", "当%s = %s时，也适合上式" % (new_latex(symbol), new_latex(1))])
                self.output.append(BaseValues([new_an]))
                self.steps.append(["", "∴ %s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
            else:
                self.steps.append(["", "当%s = %s时，不适合上式" % (new_latex(symbol), new_latex(1))])
                new_tong_xiang = BasePieceShuLie({"var": symbol, "name": a_name(symbol),
                                                  "expression": [[a1_value, range(1, 2)], [new_an, range(2, 100000)]]})
                self.output.append(new_tong_xiang)
                self.steps.append(["", "∴ %s " % (new_tong_xiang.printing())])
        self.steps.append(
            ["", "∴ %s" % "或".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in tong_xiangs])])
        self.output.append(BaseValues(tong_xiangs))
        self.label.add("求等差数列的通项公式")
        return self


class GetTongXiangGongShi002(BaseFunction):
    """
    求通项公式: a(n) = p*a(n-1)
    1. a(n) = p*a(n-1)
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 2
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """

    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        a_name = args[4]
        s_name = args[5]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert (max_index - min_index) == 1
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        answer = solve(fn, max_xiang)
        eq_right = answer[0]
        assert sl_linear_poly(eq_right, min_xiang)
        a, b = sl_linear_poly_coeffs(eq_right, min_xiang)
        assert b == 0
        new_a = str(a)
        assert new_a.find(str(symbol)) < 0
        self.steps.append(["", "依题意，得"])
        tong_xiangs = []
        for item in a1:
            item_value = item[1]
            self.steps.append(
                ["", "数列\\{%s\\}是以%s为首项, %s为公比的等比数列" % (
                    new_latex(min_xiang), new_latex(item_value), new_latex(a))])
            j = sympify('t')
            tong_xiang = j * a ** n
            self.steps.append(["", "设%s, 则" % (BaseEq([shulie_name[0](n), tong_xiang]).printing())])
            eqs = [[item_value, "!=", S.Zero]]
            new_a1 = tong_xiang.subs({n: 1})
            eqs.append(item)
            eqs.append([item_value - new_a1, S.Zero])
            eqs.append([j, "!=", S.Zero])
            if aothers:
                for eq in aothers:
                    if len(eq) == 2:
                        expr = eq[0] - eq[1]
                    else:
                        expr = eq[0] - eq[2]
                    expr = expr.subs({n: 1})
                    m = sl_xiangs(expr)
                    if m:
                        for t in m:
                            new_t = sympify(t)
                            new_t_index = new_t.args[0]
                            new_t_name = new_t.func
                            if str(new_t_name) == str(a_name):
                                new_t_value = tong_xiang.subs({n: new_t_index})
                                expr = expr.subs({new_t: new_t_value})
                            elif str(new_t_name) == str(s_name):
                                if a.free_symbols:
                                    new_t_value = new_a1 * (1 - a ** new_t_index) / (1 - a)
                                else:
                                    if a == 1:
                                        new_t_value = new_t_index * new_a1
                                    else:
                                        new_t_value = new_a1 * (1 - a ** new_t_index) / (1 - a)
                                expr = expr.subs({new_t: new_t_value})
                    if len(eq) == 2:
                        eqs.append([expr, S.Zero])
                    else:
                        eqs.append([expr, eq[1], S.Zero])
            if len(eqs) == 1:
                if len(eqs[0]) == 2:
                    self.steps.append(["", "∴ %s" % (BaseEq(eqs[0]).printing())])
                else:
                    self.steps.append(["", "∴ %s" % (BaseIneq(eqs[0]).printing())])
            else:
                self.steps.append(["", "∴ %s" % (BaseIneqs(eqs).printing())])
            solutions = MathematicaSolve().solver(BaseIneqs(eqs), BaseVariable(j)).output[0]
            self.steps.append(["", "解得: %s" % (solutions.printing())])
            tong_xiangs = sl_solutuons_subs(solutions, tong_xiang)
        tong_xiangs = set(tong_xiangs)
        tong_xiangs = list(tong_xiangs)
        self.steps.append(
            ["", "∴ %s" % "或".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in tong_xiangs])])
        self.output.append(BaseValues(tong_xiangs))
        self.label.add("求等比数列的通项公式")
        return self


class GetTongXiangGongShi003(BaseFunction):
    """
    待定系数法：求通项公式: a(n) = p*a(n-1) + q
    1. a(n) = p*a(n-1) + q
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 2
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        n_ineqs = args[3]
        a_name = args[4]
        s_name = args[5]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 1
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        answer = solve(fn, max_xiang)
        eq_right = answer[0]
        assert sl_linear_poly(eq_right, min_xiang)
        a, b = sl_linear_poly_coeffs(eq_right, min_xiang)
        new_a = str(a)
        assert new_a.find(str(symbol)) < 0
        new_b = str(b)
        assert new_b.find(str(symbol)) < 0
        assert a != 1
        assert b != 0
        self.steps.append(["", "由待定系数法，知"])
        t = sympify('t')
        dai_ding_eq = [max_xiang + t, a * (min_xiang + t)]
        self.steps.append(["", "%s" % (BaseEq(dai_ding_eq).printing())])
        t_answer = solve(a * t - t - b, t)
        self.steps.append(["", "解得：%s" % (BaseSymbolValue({t: t_answer[0]}).printing())])
        left = dai_ding_eq[0]
        left = left.subs({t: t_answer[0]})
        right = dai_ding_eq[1]
        right = right.subs({t: t_answer[0]})
        new_dai_ding_eq = [left, right]
        self.steps.append(["", "∴ %s" % (BaseEq(new_dai_ding_eq).printing())])
        self.steps.append(["", "∴数列\\{%s\\}是以%s为首项, %s为公比的等比数列" % ((new_latex(left)), new_latex(shulie_name[0](1) + t_answer[0]), new_latex(a))])
        assert len(shulie_name) == 1
        shulie_name = shulie_name[0]
        if str(shulie_name) == str(a_name):
            tong_xiangs = []
            for item in a1:
                item_value = item[1]
                tong_xiang = (item_value + b / (a - 1)) * a ** (n - 1) - b / (a - 1)
                tong_xiang = expand(tong_xiang)
                tong_xiang = simplify(tong_xiang)
                item_xiang = sl_xiangs(item_value)
                if item_xiang:
                    eq = []
                    if aothers:
                        for other in aothers:
                            expr = other[0] - other[1]
                            expr = expr.subs({n: 1})
                            m = sl_xiangs(expr)
                            if m:
                                for t in m:
                                    new_t = sympify(t)
                                    new_t_index = new_t.args[0]
                                    new_t_name = new_t.func
                                    if str(new_t_name) == str(a_name):
                                        new_t_value = tong_xiang.subs({n: new_t_index})
                                        expr = expr.subs({new_t: new_t_value})
                                        eq.append(expr)
                    if eq:
                        if len(eq) == 1:
                            jies = solve(eq[0], sympify(item_xiang[0]))
                            for jie in jies:
                                new_tong_xiang = tong_xiang.subs({sympify(item_xiang[0]): jie})
                                tong_xiangs.append(new_tong_xiang)
                    else:
                        tong_xiangs.append(tong_xiang)
                else:
                    tong_xiangs.append(tong_xiang)
            self.steps.append(["", "∴%s" % " 或 ".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in tong_xiangs])])
            self.output.append(BaseValues(tong_xiangs))
        else:
            assert len(a1) == 1
            a1_value = a1[0][1]
            sn = (a1_value + b / (a - 1)) * a ** (n - 1) - b / (a - 1)
            self.steps.append(["", "∴ %s = %s" % (new_latex(s_name(symbol)), new_latex(sn))])
            sn_1 = sn.subs({symbol: symbol - 1})
            an = sn - sn_1
            an = an.expand().simplify()
            self.steps.append(["", "∴ %s = %s - %s = %s" % (new_latex(a_name(symbol)), new_latex(s_name(symbol)), new_latex(s_name(symbol - 1)), new_latex(an))])
            m_eqs = []
            for eq in a1:
                expr = eq[0] - eq[1]
                expr = ShuLieSnExprNormalization().solver(BasePoly(expr), a_name).output[0].sympify()
                expr_xiangs = sl_xiangs(expr)
                for expr_xiang in expr_xiangs:
                    new_item = sympify(expr_xiang)
                    new_item_index = new_item.args[0]
                    new_item_value = an.subs({symbol: new_item_index})
                    expr = expr.subs({new_item: new_item_value})
                m_eqs.append([expr, S.Zero])
            if aothers:
                for eq in aothers:
                    if len(eq) == 2:
                        expr = eq[0] - eq[1]
                        expr = ShuLieSnExprNormalization().solver(BasePoly(expr), a_name).output[0].sympify()
                        expr_xiangs = sl_xiangs(expr)
                        for expr_xiang in expr_xiangs:
                            new_item = sympify(expr_xiang)
                            new_item_index = new_item.args[0]
                            new_item_value = an.subs({symbol: new_item_index})
                            expr = expr.subs({new_item: new_item_value})
                        m_eqs.append([expr, S.Zero])
                    else:
                        expr = eq[0] - eq[2]
                        expr = ShuLieSnExprNormalization().solver(BasePoly(expr), a_name).output[0].sympify()
                        expr_xiangs = sl_xiangs(expr)
                        for expr_xiang in expr_xiangs:
                            new_item = sympify(expr_xiang)
                            new_item_index = new_item.args[0]
                            new_item_value = an.subs({symbol: new_item_index})
                            expr = expr.subs({new_item: new_item_value})
                        m_eqs.append([expr, eq[1], S.Zero])
            if n_ineqs:
                for ineq in n_ineqs:
                    left, op, right = ineq
                    expr = left - right
                    expr = ShuLieSnExprNormalization().solver(BasePoly(expr), a_name).output[0].sympify()
                    expr_xiangs = sl_xiangs(expr)
                    for expr_xiang in expr_xiangs:
                        new_item = sympify(expr_xiang)
                        new_item_index = new_item.args[0]
                        new_item_value = an.subs({symbol: new_item_index})
                        expr = expr.subs({new_item: new_item_value})
                    m_eqs.append([expr, op, S.Zero])
            if len(m_eqs) == 1:
                if len(m_eqs[0]) == 2:
                    self.steps.append(["", "∴ %s" % (BaseEq(m_eqs[0]).printing())])
                else:
                    self.steps.append(["", "∴ %s" % (BaseIneq(m_eqs[0]).printing())])
            else:
                self.steps.append(["", "∴ %s" % (BaseIneqs(m_eqs).printing())])
            solutions = MathematicaSolve().solver(BaseIneqs(m_eqs)).output[0]
            self.steps.append(["", "解得: %s" % solutions.printing()])
            an = sl_solutuons_subs(solutions, an)[0]
            self.steps.append(["", "当%s > 1时, %s = %s" % (new_latex(symbol), new_latex(a_name(symbol)), new_latex(an))])
            new_a1 = an.subs({symbol: 1})
            if new_a1 - a1_value == 0:
                self.steps.append(["", "当%s = %s时，也适合上式" % (new_latex(symbol), new_latex(1))])
                self.output.append(BaseValues([an]))
                self.steps.append(["", "∴ %s = %s" % (new_latex(a_name(symbol)), new_latex(an))])
            else:
                self.steps.append(["", "当%s = %s时，不适合上式" % (new_latex(symbol), new_latex(1))])
                new_an = BasePieceShuLie({"var": symbol, "name": a_name(symbol), "expression": [[a1_value, range(1, 2)], [an, range(2, 100000)]]})
                self.output.append(new_an)
                self.steps.append(["", "∴ %s " % (new_an.printing())])
        self.label.add("待定系数法求数列通项公式")
        return self


class GetTongXiangGongShi004(BaseFunction):
    """
    累加法：求通项公式: a(n) = a(n-1) + f(n)
    1. a(n) = a(n-1) + f(n)
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 2
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """
    def solver(self, *args):
        a1 = args[0]
        dituishi = args[2]
        a_name = args[4]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 1
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        answer = solve(fn, max_xiang)
        eq_right = answer[0]
        assert sl_linear_poly(eq_right, min_xiang)
        a, b = sl_linear_poly_coeffs(eq_right, min_xiang)
        self.steps.append(["", "整理, 得"])
        self.steps.append(["", "%s = %s" % (new_latex(max_xiang), new_latex(a.simplify() * min_xiang + b))])
        assert a.simplify() == 1
        new_b = str(b)
        assert new_b.find(str(symbol)) >= 0
        eq = [sympify('t_(n)'), b]
        self.steps.append(["", "由累加法，得"])
        self.steps.append(["", "令 %s" % (BaseEq(eq).printing())])
        from mathsolver.functions.shulie.QianNXiangHe import ShuLieQiuHe
        stepsolver = ShuLieQiuHe().solver(BaseEq(eq).sympify(), 1, min_index)
        self.steps += stepsolver.steps
        if isinstance(stepsolver.output[0], BasePieceShuLie):
            sn = stepsolver.output[0].sympify()
            an_values = []
            for item in sn:
                an_value = item[1] + a1[0][1]
                an_value = an_value.subs({symbol: symbol - 1})
                an_value = MathematicaSimplify().solver(BasePoly(an_value)).output[0].sympify()
                an_values.append([an_value, item[2]])
            tong_xiang = BasePieceShuLie({"var": symbol, "name": a_name(symbol), "expression": an_values})
            self.steps.append(["", "%s" % tong_xiang.printing()])
            self.output.append(tong_xiang)
        else:
            assert len(shulie_name) == 1
            shulie_name = shulie_name[0]
            sn = stepsolver.output[0].sympify()
            tong_xiangs = []
            for item in a1:
                item_value = item[1]
                for val in sn:
                    tong_xiang = val + item_value
                    tong_xiang = tong_xiang.subs({symbol: symbol - 1})
                    tong_xiang = expand(tong_xiang)
                    tong_xiang = simplify(tong_xiang)
                    tong_xiangs.append(tong_xiang)
            if str(shulie_name) == str(a_name):
                self.steps.append(["", "∴ %s" % "或".join(["%s = %s" % (new_latex(a_name(symbol)), new_latex(v)) for v in tong_xiangs])])
                self.output.append(BaseValues(tong_xiangs))
            else:
                assert len(tong_xiangs) == 1
                new_sn = tong_xiangs[0]
                new_sn_1 = new_sn.subs({symbol: symbol - 1})
                new_an = new_sn - new_sn_1
                new_an = new_an.expand().simplify()
                new_a1 = new_an.subs({symbol: 1})
                a1_value = a1[0][1]
                if a1_value - new_a1 == 0:
                    self.steps.append(["", "当%s = %s时，也适合上式" % (new_latex(symbol), new_latex(1))])
                    self.output.append(BaseValues([new_an]))
                    self.steps.append(["", "∴ %s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
                else:
                    self.steps.append(["", "当%s = %s时，不适合上式" % (new_latex(symbol), new_latex(1))])
                    new_tong_xiang = BasePieceShuLie({"var": symbol, "name": a_name(symbol), "expression": [[a1_value, range(1, 2)], [new_an, range(2, 100000)]]})
                    self.output.append(new_tong_xiang)
                    self.steps.append(["", "∴ %s " % (new_tong_xiang.printing())])
        self.label.add("累加法求数列的通项公式")
        return self


class GetTongXiangGongShi005(BaseFunction):
    """
    求通项公式: a(n) = k * a(n-1) + a*n + b
    1. a(n) = k * a(n-1) + a*n + b
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 2
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """
    def solver(self, *args):
        a1 = args[0]
        dituishi = args[2]
        a_name = args[4]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 1
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        answer = solve(fn, max_xiang)
        eq_right = answer[0]
        assert sl_linear_poly(eq_right, min_xiang)
        k, new_fn = sl_linear_poly_coeffs(eq_right, min_xiang)
        new_k = str(k)
        assert new_k.find(str(symbol)) < 0
        assert sl_linear_n(new_fn, symbol)
        a, b = sl_linear_poly_coeffs(new_fn, symbol)
        da = sympify('A')
        db = sympify('B')
        new_eq = [max_xiang + da * (symbol + 1) + db, k * (min_xiang + da * symbol + db)]
        self.steps.append(["", "可设 %s" % (BaseEq(new_eq).printing())])
        new_eqs = [[(k - 1) * da, a], [(k - 1) * db - da, b]]
        self.steps.append(["", "∴%s" % (BaseEqs(new_eqs).printing())])
        new_a = a / (k - 1)
        new_b = b / (k - 1) + a / (k - 1) ** 2
        assert str(new_a) != 'nan'
        self.steps.append(
            ["", "解得：%s = %s , %s = %s" % (new_latex(da), new_latex(new_a), new_latex(db), new_latex(new_b))])
        target_an = min_xiang + new_a * n + new_b
        target_a1 = []
        shulie_name = shulie_name[0]
        if str(shulie_name) == str(a_name):
            for t in a1:
                target_a1_value = t[1] + new_a + new_b
                target_a1.append(target_a1_value)
                self.steps.append(["", "∴数列\\{%s\\}是以%s为首项, %s为公比的等比数列" % (
                    new_latex(target_an), new_latex(target_a1_value), new_latex(k))])
            tong_xiangs = []
            for t in target_a1:
                tong_xiang = t * k ** (n - 1) - new_a * n - new_b
                tong_xiang = expand(tong_xiang)
                tong_xiang = simplify(tong_xiang)
                tong_xiangs.append(tong_xiang)
            self.steps.append(
                ["", "%s" % "或".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in tong_xiangs])])
            self.output.append(BaseValues(tong_xiangs))
        else:
            target_a1_value = target_an.subs({symbol: 1})
            target_a1_value = ShuLieSnExprNormalization().solver(BasePoly(target_a1_value), a_name).output[
                0].sympify()
            m_eqs = []
            if a1:
                m_eqs.extend(a1)
            solutions = MathematicaSolve().solver(BaseIneqs(m_eqs)).output[0]
            target_a1_value = sl_solutuons_subs(solutions, target_a1_value)
            assert len(target_a1_value) == 1
            target_a1_value = target_a1_value[0]
            self.steps.append(["", "∴数列\\{%s\\}是以%s为首项, %s为公比的等比数列" % (
                new_latex(target_an), new_latex(target_a1_value), new_latex(k))])
            sn = target_a1_value * k ** (n - 1) - new_a * n - new_b
            sn = expand(sn)
            sn = simplify(sn)
            self.steps.append(["", "∴%s = %s" % (new_latex(min_xiang), new_latex(sn))])
            self.steps.append(["", "当%s > 1时" % (new_latex(symbol))])
            new_an = sn.subs({symbol: symbol}) - sn.subs({symbol: symbol - 1})
            new_an = new_an.expand().simplify()
            new_a1 = new_an.subs({symbol: 1})
            self.steps.append(["", "%s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
            if a1[0][1] == new_a1:
                self.steps.append(["", "当%s = %s时，也适合上式" % (new_latex(symbol), new_latex(1))])
                self.output.append(BaseValues([new_an]))
                self.steps.append(["", "∴ %s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
            else:
                self.steps.append(["", "当%s = %s时，不适合上式" % (new_latex(symbol), new_latex(1))])
                new_an = BasePieceShuLie({"var": symbol, "name": a_name(symbol),
                                          "expression": [[new_a1, range(1, 2)], [new_an, range(2, 100000)]]})
                self.output.append(new_an)
                self.steps.append(["", "∴ %s " % (new_an.printing())])
        self.label.add("构造法求数列的通项公式: 类型一")
        return self


class GetTongXiangGongShi006(BaseFunction):
    """
    求通项公式: a(n) = k * a(n-1) + a*n**2 + b*n + c
    1. a(n) = k * a(n-1) + a*n**2 + b*n + c
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 2
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        a_name = args[4]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 1
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        answer = solve(fn, max_xiang)
        eq_right = answer[0]
        assert sl_linear_poly(eq_right, min_xiang)
        k, new_fn = sl_linear_poly_coeffs(eq_right, min_xiang)
        new_k = str(k)
        assert new_k.find(str(symbol)) < 0
        assert sl_er_ci_n(new_fn, symbol)
        poly = Poly(new_fn.as_expr(), symbol)
        a, b, c = poly.all_coeffs()
        a_1 = sympify('a1')
        b_1 = sympify('b1')
        c_1 = sympify('c1')
        q = sympify('q')
        new_bn = min_xiang + a_1 * symbol ** 2 + b_1 * symbol + c_1
        new_bn1 = max_xiang + a_1 * (symbol + 1) ** 2 + b_1 * (symbol + 1) + c_1
        self.steps.append(["", "设%s = %s * (%s), 则" % (new_latex(new_bn1), new_latex(q), new_latex(new_bn))])
        eqs = [[q, k], [a, a_1 * q - a_1], [b, b_1 * q - 2 * a_1 - b_1], [c, q * c_1 - a_1 - b_1 - c_1]]
        self.steps.append(["", "∴ %s" % (BaseEqs(eqs).printing())])
        solutions = MathematicaSolve().solver(BaseEqs(eqs)).output[0].sympify()
        self.steps.append(["", "解得: %s" % (BaseSymbolValue(solutions).printing())])
        answer1 = sl_search_multiple(solutions, new_bn)[0]
        new_bn = new_bn.subs(answer1)
        answer2 = sl_search_multiple(solutions, new_bn1)[0]
        new_bn1 = new_bn.subs(answer2)
        answer3 = sl_search_multiple(solutions, q)[0]
        gongbi = q.subs(answer3)
        self.steps.append(["", "∴ %s = %s * (%s)" % (new_latex(new_bn1), new_latex(gongbi), new_latex(new_bn))])
        assert len(a1) == 1
        target_an = new_bn
        target_a1_value = target_an.subs({symbol: 1})
        target_a1_value = target_a1_value.subs({a_name(1): a1[0][1]})
        target_a1_value = target_a1_value.expand().simplify()
        self.steps.append(["", "∴数列\\{%s\\}是以%s为首项, %s为公比的等比数列" % (
            new_latex(target_an), new_latex(target_a1_value), new_latex(gongbi))])
        target_an_value = target_a1_value * gongbi ** (symbol - 1)
        self.steps.append(["", "∴ %s = %s" % (new_latex(target_an), new_latex(target_an_value))])
        tongxiang = solve(target_an - target_an_value, min_xiang)[0]
        if str(shulie_name[0]) == str(a_name):
            self.steps.append(["", "∴ %s = %s" % (new_latex(min_xiang), new_latex(tongxiang))])
            self.output.append(BaseValues([tongxiang]))
        else:
            sn = tongxiang
            new_sn = ShuLieSnExprNormalization().solver(BasePoly(sn), a_name).output[0].sympify()
            m_eqs = []
            m_eqs.extend(a1)
            if aothers:
                for eq in aothers:
                    expr = eq[0] - eq[1]
                    new_expr = ShuLieSnExprNormalization().solver(BasePoly(expr), a_name).output[0].sympify()
                    new_expr_xiangs = sl_xiangs(new_expr)
                    for new_expr_xiang in new_expr_xiangs:
                        new_item = sympify(new_expr_xiang)
                        new_item_index = new_item.args[0]
                        if new_item_index == 1:
                            new_item_value = new_sn.subs({symbol: new_item_index})
                        else:
                            new_item_value = new_sn.subs({symbol: new_item_index + 1}) - new_sn.subs(
                                {symbol: new_item_index})
                        new_item_value = new_item_value.expand().simplify()
                        new_expr = new_expr.subs({new_item: new_item_value})
                    m_eqs.append([new_expr, 0])
            solutions = MathematicaSolve().solver(BaseIneqs(m_eqs), BaseVariables(new_expr_xiangs)).output[0]
            new_sn = sl_solutuons_subs(solutions, new_sn)
            assert len(a1) == 1
            assert len(new_sn) == 1
            new_sn = new_sn[0]
            self.steps.append(["", "∴ %s = %s" % (new_latex(min_xiang), new_latex(new_sn))])
            self.steps.append(["", "当%s > 1时" % (new_latex(symbol))])
            a1[0][1] = sl_solutuons_subs(solutions, a1[0][1])[0]
            new_an = new_sn.subs({symbol: symbol}) - new_sn.subs({symbol: symbol - 1})
            new_an = new_an.expand().simplify()
            self.steps.append(["", "%s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
            new_a1 = new_an.subs({symbol: 1})
            if new_a1 - a1[0][1] == 0:
                self.steps.append(["", "当%s = %s时，也适合上式" % (new_latex(symbol), new_latex(1))])
                self.steps.append(["", "∴ %s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
                self.output.append(BaseValues([new_an]))
            else:
                tongxiang = BasePieceShuLie({"var": symbol, "name": a_name(symbol),
                                             "expression": [[a1[0][1], range(1, 2)], [new_an, range(2, 100000)]]})
                self.output.append(tongxiang)
                self.steps.append(["", "∴ %s " % (tongxiang.printing())])
        self.label.add("构造法求数列的通项公式: 类型二")
        return self


class GetTongXiangGongShi007(BaseFunction):
    """
    求通项公式: a(n) = A * a(n-1) + f(n)*q**n
    1. a(n) = A * a(n-1) + B*q**n
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 2
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        n_ineqs = args[3]
        a_name = args[4]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 1
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        answer = solve(fn, max_xiang)
        eq_right = answer[0]
        assert sl_linear_poly(eq_right, min_xiang)
        da, new_fn = sl_linear_poly_coeffs(eq_right, min_xiang)
        new_a = str(da)
        assert new_a.find(str(symbol)) < 0
        new_right = cancel(eq_right / da ** (symbol + 1))
        new_right = expand(new_right)
        new_right = simplify(new_right)
        new_eq = [max_xiang / da ** (symbol + 1), new_right]
        self.steps.append(["", "等式两边都除以%s, 得" % (new_latex(da ** (symbol + 1)))])
        self.steps.append(["", "%s" % (BaseEq(new_eq).printing())])
        cn_value = min_xiang / da ** symbol
        cn_name = sympify('C_')
        cn = cn_name(symbol)
        c1 = []
        for item in a1:
            expr = item[0] - item[1]
            if expr == 0:
                expr_answers = item[1]
            else:
                expr_answers = solve(expr, a_name(1))[0]
            c1.append([cn_name(1), expr_answers / da])
        self.steps.append(["", "令 %s = %s, 则" % (new_latex(cn), new_latex(cn_value))])
        new_fn = fn.subs(
            {min_xiang: cn_name(symbol) * da ** symbol, max_xiang: cn_name(symbol + 1) * da ** (symbol + 1)})
        new_shulie_name = sl_shulie_name(new_fn)
        assert len(new_shulie_name) == 1
        new_answer = solve(new_fn, cn_name(symbol + 1))
        assert len(new_answer) == 1
        new_answer = new_answer[0]
        self.steps.append(["", "%s" % (BaseEq([cn_name(symbol + 1), new_answer]).printing())])
        cls = [GetTongXiangGongShi001, GetTongXiangGongShi002, GetTongXiangGongShi003, GetTongXiangGongShi004,
               GetTongXiangGongShi005]
        stepsolver = None
        for cl in cls:
            try:
                stepsolver = cl(verbose=True).solver(c1, [], [[cn_name(symbol + 1), new_answer]], n_ineqs,
                                                     sympify('C_'), sympify('T_'))
                break
            except Exception:
                pass
        assert stepsolver
        self.steps += stepsolver.steps
        cn_tongxiang = stepsolver.output[0].sympify()
        tongxiangs = []
        for val in cn_tongxiang:
            an = val * da ** symbol
            an = expand(an)
            an = simplify(an)
            tongxiangs.append(an)
        new_tong_xiangs = []
        for tongxiang in tongxiangs:
            m_eqs = []
            m_eqs.extend(a1)
            if aothers:
                for eq in aothers:
                    expr = eq[0] - eq[1]
                    expr = ShuLieSnExprNormalization().solver(BasePoly(expr), a_name).output[0].sympify()
                    expr_xiangs = sl_xiangs(expr)
                    for expr_xiang in expr_xiangs:
                        new_item = sympify(expr_xiang)
                        new_item_index = new_item.args[0]
                        new_item_value = tongxiang.subs({symbol: new_item_index})
                        expr = expr.subs({new_item: new_item_value})
                    m_eqs.append([expr, S.Zero])
            solutions = MathematicaSolve().solver(BaseIneqs(m_eqs)).output[0]
            tongxiang = sl_solutuons_subs(solutions, tongxiang)
            new_tong_xiangs.extend(tongxiang)
        self.steps.append(
            ["", "∴ %s" % "或".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in new_tong_xiangs])])
        self.output.append(BaseValues(new_tong_xiangs))
        self.label.add("构造法求数列的通项公式: 类型三")
        return self


class GetTongXiangGongShi008(BaseFunction):
    """
    倒数变换：求通项公式: a(n+1) = c*a(n) / (k * a(n) + d)
    1. a(n+1) = c*a(n) / (k * a(n) + d)
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 2
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """
    def solver(self, *args):
        a1 = args[0]
        dituishi = args[2]
        n_ineqs = args[3]
        a_name = args[4]
        s_name = args[5]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 1
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        answer = solve(fn, max_xiang)
        eq_right = answer[0]
        assert sl_frac_poly(eq_right, min_xiang)
        fenzhi, fenmu = fraction(eq_right)
        c, fenzhi_b = sl_linear_poly_coeffs(fenzhi, shulie_name[0](n))
        k, d = sl_linear_poly_coeffs(fenmu, shulie_name[0](n))
        assert (str(c)).find(str(symbol)) < 0
        assert fenzhi_b == 0
        assert (str(k)).find(str(symbol)) < 0
        assert (str(d)).find(str(symbol)) < 0
        new_eq_left = 1 / max_xiang
        new_eq_right = 1 / eq_right
        new_eq_right = cancel(new_eq_right)
        new_eq_right = expand(new_eq_right)
        new_eq_right = simplify(new_eq_right)
        self.steps.append(["等式两边取倒数，得", BaseEq([new_eq_left, new_eq_right]).printing()])
        cn_value = 1 / min_xiang
        cn_name = sympify('C_')
        cn = cn_name(symbol)
        cn1 = cn_name(symbol + 1)
        c1 = []
        for item in a1:
            c1.append([cn_name(1), 1 / item[1]])
        new_eq2_left = cn1
        new_eq2_right = d / c * cn + k / c
        new_eq2_right = simplify(new_eq2_right)
        new_eq2 = [new_eq2_left, new_eq2_right]
        self.steps.append(["令 %s = %s, 则" % (new_latex(cn), new_latex(cn_value)), BaseEq(new_eq2).printing()])
        cls = [GetTongXiangGongShi001, GetTongXiangGongShi002, GetTongXiangGongShi003]
        stepsolver = None
        for cl in cls:
            try:
                stepsolver = cl(verbose=True).solver(c1, [], [new_eq2], n_ineqs, sympify('C_'), sympify('S_'))
                break
            except Exception:
                pass
        if not stepsolver:
            raise 'try fail'
        self.steps += stepsolver.steps
        cn_tongxiang = stepsolver.output[0].sympify()
        if str(shulie_name[0]) == str(s_name):
            assert len(cn_tongxiang) == 1
            new_sn = 1 / cn_tongxiang[0]
            new_sn_1 = new_sn.subs({symbol: symbol - 1})
            new_an = new_sn - new_sn_1
            new_an = new_an.expand().simplify()
            new_a1 = new_an.subs({symbol: 1})
            a1_value = a1[0][1]
            if a1_value - new_a1 == 0:
                self.steps.append(["", "当%s = %s时，也适合上式" % (new_latex(symbol), new_latex(1))])
                self.output.append(BaseValues([new_an]))
                self.steps.append(["", "∴ %s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
            else:
                self.steps.append(["", "当%s = %s时，不适合上式" % (new_latex(symbol), new_latex(1))])
                new_tong_xiang = BasePieceShuLie({"var": symbol, "name": a_name(symbol),
                                                  "expression": [[a1_value, range(1, 2)], [new_an, range(2, 100000)]]})
                self.output.append(new_tong_xiang)
                self.steps.append(["", "∴ %s " % (new_tong_xiang.printing())])
        else:
            tong_xiangs = []
            for val in cn_tongxiang:
                an = 1 / val
                an = expand(an)
                an = simplify(an)
                tong_xiangs.append(an)
            self.steps.append(
                ["", "∴ %s" % "或".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in tong_xiangs])])
            self.output.append(BaseValues(tong_xiangs))
        self.label.add("构造法求数列的通项公式: 倒数变换")
        return self


class GetTongXiangGongShi009(BaseFunction):
    """
    特征根法：求通项公式: a(n+1) = (A*a(n) + B) / (C * a(n) + D)
    1. a(n+1) = (A*a(n) + B) / (C * a(n) + D)
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 2
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        n_ineqs = args[3]
        a_name = args[4]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        shulie_name = shulie_name[0]
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 1
        max_xiang = shulie_name(max_index)
        min_xiang = shulie_name(min_index)
        solutions = MathematicaSolve().solver(BaseEq([fn, S.Zero]), BaseVariable(max_xiang)).output[0]
        answers = sl_solutuons_subs(solutions, max_xiang)
        assert len(answers) == 1
        eq_right = answers[0]
        eq_right = cancel(eq_right)
        assert sl_frac_poly(eq_right, min_xiang)
        fenzhi, fenmu = fraction(eq_right)
        da, db = sl_linear_poly_coeffs(fenzhi, shulie_name(symbol))
        dc, dd = sl_linear_poly_coeffs(fenmu, shulie_name(symbol))
        assert (str(da)).find(str(symbol)) < 0
        assert (str(db)).find(str(symbol)) < 0
        assert (str(dc)).find(str(symbol)) < 0
        assert dc != 0
        assert (str(dd)).find(str(symbol)) < 0
        te_zheng_eq = [x, (da * x + db) / (dc * x + dd)]
        self.steps.append(["", "其特征方程为%s" % (BaseEq(te_zheng_eq).printing())])
        pangbieshi = (dd - da) ** 2 - 4 * dc * (-db)
        pangbieshi = expand(pangbieshi)
        pangbieshi = simplify(pangbieshi)
        pangbieshi_symbols = pangbieshi.free_symbols
        assert not pangbieshi_symbols
        assert pangbieshi >= 0
        tsolutions = MathematicaSolve().solver(BaseEq(te_zheng_eq)).output[0]
        self.steps.append(["", "解得: %s" % (tsolutions.printing())])
        solutions = tsolutions.sympify()
        solutions = list(solutions[x])
        if len(solutions) == 1:
            new_eq_left = 1 / (max_xiang - solutions[0])
            new_eq_right = 1 / (min_xiang - solutions[0]) + sympify('c')
            self.steps.append(["", "令%s" % (BaseEq([new_eq_left, new_eq_right]).printing())])
            cn = 1 / (min_xiang - solutions[0])
            c1 = cn.subs({symbol: 1})
            cn_d = sympify('c')
            self.steps.append(["", "数列\\{%s\\}是以%s为首项，以%s为公差的等差数列" % (new_latex(cn), new_latex(c1), new_latex(cn_d))])
            cn_value = c1 + (n - 1) * cn_d
            self.steps.append(["", "∴ %s = %s" % (new_latex(cn), new_latex(cn_value))])
            tsolutions = MathematicaSolve().solver(BaseEq([cn, cn_value]), BaseVariable(min_xiang)).output[0]
            min_xiang = sl_solutuons_subs(tsolutions, min_xiang)
            solution_an = solve(cn - cn_value, min_xiang)
            an_value = solution_an[0]
            an_value = ShuLieSnExprNormalization().solver(BasePoly(an_value), a_name).output[0].sympify()
            self.steps.append(["", "∴ %s = %s" % (new_latex(min_xiang), new_latex(an_value))])
            m_eqs = []
            if a1:
                for eq1 in a1:
                    expr1 = eq1[0] - eq1[1]
                    expr1 = sl_expr_to_an_value(expr1, a_name, shulie_name, an_value, symbol)
                    m_eqs.append([expr1, S.Zero])
            f1 = fn.subs({symbol: 1})
            f1 = sl_expr_to_an_value(f1, a_name, shulie_name, an_value, symbol)
            m_eqs.append([f1, S.Zero])
            if aothers:
                print("GetTongXiangGongShi009")
            if n_ineqs:
                print("GetTongXiangGongShi009")
            if len(m_eqs) == 1:
                if len(m_eqs[0]) == 2:
                    self.steps.append(["", "%s" % BaseEq(m_eqs[0]).printing()])
                else:
                    self.steps.append(["", "%s" % BaseIneq(m_eqs[0]).printing()])
            else:
                self.steps.append(["", "%s" % BaseIneqs(m_eqs).printing()])
            m_solutions = MathematicaSolve().solver(BaseIneqs(m_eqs)).output[0]
            self.steps.append(["", "解得: %s" % (m_solutions.printing())])
            an = sl_solutuons_subs(m_solutions, an_value)
            if str(shulie_name) == str(a_name):
                tong_xiangs = an
                self.steps.append(
                    ["", "∴ %s" % ("或".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in tong_xiangs]))])
                self.output.append(BaseNumbers(tong_xiangs))
            else:
                assert len(an) == 1
                sn = an[0]
                new_a1 = sn.subs({symbol: 1})
                self.steps.append(["", "当%s > 1时," % (new_latex(symbol))])
                new_an = sn.subs({symbol: symbol}) - sn.subs({symbol: symbol - 1})
                new_an = new_an.expand().simplify()
                self.steps.append(["", "%s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
                if new_a1 == a1[0][1]:
                    self.steps.append(["", "当%s = 1时,上式也成立" % (new_latex(symbol))])
                    self.steps.append(["", "∴ %s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
                    self.output.append(BaseNumbers([new_an]))
                else:
                    self.steps.append(["", "当%s = 1时,上式不成立" % (new_latex(symbol))])
                    tong_xiang = BasePieceShuLie({"var": symbol, "name": a_name(symbol),
                                                  "expression": [[a1[0][1], range(1, 2)], [new_an, range(2, 100000)]]})
                    self.output.append(tong_xiang)
                    self.steps.append(["", "∴ %s " % (tong_xiang.printing())])
        elif len(solutions) == 2:
            new_eq_left = (max_xiang - solutions[0]) / (max_xiang - solutions[1])
            new_eq_right = sympify('c') * (min_xiang - solutions[0]) / (min_xiang - solutions[1])
            self.steps.append(["", "令%s" % (BaseEq([new_eq_left, new_eq_right]).printing())])
            cn = (min_xiang - solutions[0]) / (min_xiang - solutions[1])
            c1 = cn.subs({symbol: 1})
            cn_q = sympify('c')
            self.steps.append(
                ["",
                 "∴数列\\{%s\\}是以%s为首项，以%s为公比的等比数列" % (new_latex(cn), new_latex(c1), new_latex(cn_q))])
            cn_value = c1 * cn_q ** (n - 1)
            self.steps.append(["", "∴ %s = %s" % (new_latex(cn), new_latex(cn_value))])
            solution_an = solve(cn - cn_value, min_xiang)
            an_value = solution_an[0]
            self.steps.append(["", "∴ %s = %s" % (new_latex(min_xiang), new_latex(an_value))])
            m_eqs = []
            if a1:
                for eq1 in a1:
                    expr1 = eq1[0] - eq1[1]
                    expr1 = sl_expr_to_an_value(expr1, a_name, shulie_name, an_value, symbol)
                    m_eqs.append([expr1, S.Zero])
            f1 = fn.subs({symbol: 1})
            f1 = sl_expr_to_an_value(f1, a_name, shulie_name, an_value, symbol)
            m_eqs.append([f1, S.Zero])
            if aothers:
                print("GetTongXiangGongShi009")
            if n_ineqs:
                print("GetTongXiangGongShi009")
            if len(m_eqs) == 1:
                if len(m_eqs[0]) == 2:
                    self.steps.append(["", "%s" % BaseEq(m_eqs[0]).printing()])
                else:
                    self.steps.append(["", "%s" % BaseIneq(m_eqs[0]).printing()])
            else:
                self.steps.append(["", "%s" % BaseIneqs(m_eqs).printing()])
            m_solutions = MathematicaSolve().solver(BaseIneqs(m_eqs)).output[0]
            self.steps.append(["", "解得: %s" % (m_solutions.printing())])
            an = sl_solutuons_subs(m_solutions, an_value)
            if str(shulie_name) == str(a_name):
                tong_xiangs = an
                self.steps.append(
                    ["", "∴ %s" % "或".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in tong_xiangs])])
                self.output.append(BaseNumbers(tong_xiangs))
            else:
                assert len(an) == 1
                sn = an[0]
                new_a1 = sn.subs({symbol: 1})
                self.steps.append(["", "当%s > 1时," % (new_latex(symbol))])
                new_an = sn.subs({symbol: symbol}) - sn.subs({symbol: symbol - 1})
                new_an = new_an.expand().simplify()
                self.steps.append(["", "%s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
                if new_a1 == a1[0][1]:
                    self.steps.append(["", "当%s = 1时,上式也成立" % (new_latex(symbol))])
                    self.steps.append(["", "∴ %s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
                    self.steps.append(BaseNumbers([new_an]))
                else:
                    self.steps.append(["", "当%s = 1时,上式不成立" % (new_latex(symbol))])
                    tong_xiang = BasePieceShuLie({"var": symbol, "name": a_name(symbol),
                                                  "expression": [[a1[0][1], range(1, 2)], [new_an, range(2, 100000)]]})
                    self.output.append(tong_xiang)
                    self.steps.append(["", "∴ %s " % (tong_xiang.printing())])
        else:
            raise Exception('Try Error!')
        self.label.add("求数列的通项公式: 分式型特征根法")
        return self


class GetTongXiangGongShi010(BaseFunction):
    """
    等差中项性质：求通项公式: a(n+2) = 2*a(n+1) - a(n)
    1. a(n+2) = 2*a(n+1) - a(n)
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 3
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        a_name = args[4]
        s_name = args[5]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 3
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 2
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        answer = solve(fn, max_xiang)
        eq_right = answer[0]
        assert sl_benimaru_poly(eq_right)
        p, q = sl_benimaru_poly_coeffs(eq_right)
        assert (str(p)).find(str(symbol)) < 0
        assert (str(q)).find(str(symbol)) < 0
        chang_liang = eq_right - p * a_name(min_index + 1) - q * min_xiang
        assert chang_liang == 0
        assert p == 2 and q == -1
        self.steps.append(["", "由等差中项的性质，知"])
        self.steps.append(["", "%s是等差数列" % (new_latex(min_xiang))])
        tongxiangs = []
        for item in a1:
            item_value = item[1]
            k = sympify('k')
            b = sympify('t')
            tongxiang = k * n + b
            self.steps.append(["", "设%s,得" % (BaseEq([min_xiang, tongxiang]).printing())])
            eqs = []
            eqs_print = []  # 输出方程组
            new_a1 = tongxiang.subs({n: 1})
            eqs.append(item_value - new_a1)
            eqs_print.append([item_value - new_a1, S.Zero])
            if aothers:
                for eq in aothers:
                    expr = eq[0] - eq[1]
                    expr = expr.subs({n: 1})
                    m = sl_xiangs(expr)
                    if m:
                        for t in m:
                            new_t = sympify(t)
                            new_t_index = new_t.args[0]
                            new_t_name = new_t.func
                            if str(new_t_name) == str(a_name):
                                new_t_value = tongxiang.subs({n: new_t_index})
                                expr = expr.subs({new_t: new_t_value})
                            elif str(new_t_name) == str(s_name):
                                new_t_value = new_t_index * new_a1 + new_t_index * (new_t_index - 1) * k / 2
                                expr = expr.subs({new_t: new_t_value})
                    eqs.append(expr)
                    eqs_print.append([expr, S.Zero])
            self.steps.append(["", "∴ %s" % (BaseEqs(eqs_print).printing())])
            type_list, type_xiangs, solutions = sl_solve_eqs(eqs, a_name, k, b)
            if solutions:
                self.steps.append(["", "解得：%s" % (BaseSymbolValue(solutions).printing())])
            if solutions:
                for solutions_keys, solutions_values in solutions.items():
                    new_tong_xiang = tongxiang
                    for value in solutions_values:
                        for index, key in enumerate(solutions_keys):
                            if key == type_xiangs[1]:
                                new_tong_xiang = new_tong_xiang.subs({type_xiangs[1]: value[index]})
                            elif key == type_xiangs[2]:
                                new_tong_xiang = new_tong_xiang.subs({type_xiangs[2]: value[index]})
                    tongxiangs.append(new_tong_xiang)
        self.steps.append(
            ["", "∴%s" % " 或 ".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in tongxiangs])])
        self.output.append(BaseValues(tongxiangs))
        self.label.add("等差中项的性质求数列通项公式")
        return self


class GetTongXiangGongShi011(BaseFunction):
    """
    特征根法：求通项公式: a(n+2) = p*a(n+1) + q*a(n)
    1. a(n+2) = p*a(n+1) + q*a(n)
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 3
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        a_name = args[4]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 3
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 2
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        answer = solve(fn, max_xiang)
        eq_right = answer[0]
        assert sl_benimaru_poly(eq_right)
        p, q = sl_benimaru_poly_coeffs(eq_right)
        chang_liang = eq_right - p * a_name(min_index + 1) - q * min_xiang
        assert chang_liang == 0
        assert (str(p)).find(str(symbol)) < 0
        assert (str(q)).find(str(symbol)) < 0
        self.steps.append(["", "其特征方程为%s" % (BaseEq([x ** 2 - p * x - q, S.Zero]).printing())])
        panbieshi = (-p) ** 2 - 4 * 1 * (-q)
        panbieshi = expand(panbieshi)
        panbieshi = simplify(panbieshi)
        panbieshi_symbols = panbieshi.free_symbols
        assert not panbieshi_symbols
        assert panbieshi >= 0
        solutions = solve(x ** 2 - p * x - q, x)
        assert solutions
        if len(solutions) == 1:
            self.steps.append(["", "解得: %s" % (BaseEq([x, solutions[0]]).printing())])
            c1 = simplify('c1')
            c2 = simplify('c2')
            tongxiang = (c1 + c2 * n) * solutions[0] ** n
            self.steps.append(["", "令 %s" % (BaseEq([shulie_name[0](n), tongxiang]).printing())])
        else:
            self.steps.append(
                ["", "解得: %s = %s 或 %s" % (new_latex(x), new_latex(solutions[0]), new_latex(solutions[1]))])
            c1 = simplify('c1')
            c2 = simplify('c2')
            tongxiang = c1 * solutions[0] ** n + c2 * solutions[1] ** n
            self.steps.append(["", "令 %s" % (BaseEq([shulie_name[0](n), tongxiang]).printing())])
        tongxiangs = []
        for item in a1:
            item_value = item[1]
            eqs = []
            new_a1 = tongxiang.subs({n: 1})
            eqs.append([item_value - new_a1, S.Zero])
            if aothers:
                for eq in aothers:
                    expr = eq[0] - eq[1]
                    expr = expr.subs({n: 1})
                    m = sl_xiangs(expr)
                    if m:
                        for t in m:
                            new_t = sympify(t)
                            new_t_index = new_t.args[0]
                            new_t_name = new_t.func
                            if str(new_t_name) == str(a_name):
                                new_t_value = tongxiang.subs({n: new_t_index})
                                expr = expr.subs({new_t: new_t_value})
                    eqs.append([expr, S.Zero])
            self.steps.append(["", "∴ %s" % (BaseEqs(eqs).printing())])
            solutions = MathematicaSolve().solver(BaseEqs(eqs)).output[0].sympify()
            if solutions:
                self.steps.append(["", "解得：%s" % (BaseSymbolValue(solutions).printing())])
                answer = sl_search_multiple(solutions, tongxiang)
                for ans in answer:
                    new_tong_xiang = tongxiang
                    new_tong_xiang = new_tong_xiang.subs(ans)
                    new_tong_xiang = new_tong_xiang.expand().simplify()
                    tongxiangs.append(new_tong_xiang)
        self.steps.append(
            ["", "∴%s" % " 或 ".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in tongxiangs])])
        self.output.append(BaseValues(tongxiangs))
        self.label.add("求数列的通项公式: 多项式型特征根法")
        return self


class GetTongXiangGongShi012(BaseFunction):
    """
    配凑法：求通项公式: a(n+2) = p*a(n+1) + q*a(n) + k
    1. a(n+2) = p*a(n+1) + q*a(n) + k
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 3
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        a_name = args[4]
        s_name = args[5]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 3
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 2
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        answer = solve(fn, max_xiang)
        eq_right = answer[0]
        assert sl_benimaru_poly(eq_right)
        p, q = sl_benimaru_poly_coeffs(eq_right)
        changliang = eq_right - p * a_name(min_index + 1) - q * min_xiang
        assert (str(changliang)).find(str(symbol)) < 0
        assert changliang != 0
        assert (str(p)).find(str(symbol)) < 0
        assert (str(q)).find(str(symbol)) < 0
        a = sympify('a')
        b = sympify('b')
        bn = a_name(min_index + 1) + a * a_name(min_index)
        bn1 = a_name(max_index) + a * a_name(max_index - 1)
        self.steps.append(["", "依题意，得"])
        self.steps.append(["", "%s = %s %s (%s) + %s" % (
            new_latex(bn1), new_latex(b), new_latex("\\cdot"), new_latex(bn), new_latex(changliang))])
        eqs = [[b - a, p], [b * a, q]]
        self.steps.append(["", "%s" % (BaseEqs(eqs)).printing()])
        solutions = MathematicaSolve().solver(BaseEqs(eqs)).output[0].sympify()
        assert solutions
        self.steps.append(["", "解得：%s" % (BaseSymbolValue(solutions).printing())])
        answer_bn = sl_search_multiple(solutions, bn)
        for ans in answer_bn:
            bn = bn.subs(ans)
        answer_bn1 = sl_search_multiple(solutions, bn1)
        for ans in answer_bn1:
            bn1 = bn1.subs(ans)
        answer_a = sl_search_multiple(solutions, a)
        for ans in answer_a:
            a = a.subs(ans)
        answer_b = sl_search_multiple(solutions, b)
        for ans in answer_b:
            b = b.subs(ans)
        self.steps.append(["", "∴ %s = %s %s (%s) + %s" % (
            new_latex(bn1), new_latex(b), new_latex("\\cdot"), new_latex(bn), new_latex(changliang))])
        t_name = sympify('t_')
        self.steps.append(["", "设%s = %s, 则" % (new_latex(t_name(n)), new_latex(bn))])
        self.steps.append(["", "%s = %s %s %s + %s" % (
            new_latex(t_name(n + 1)), new_latex(b), new_latex("\\cdot"), new_latex(t_name(n)), new_latex(changliang))])
        t1 = bn.subs({n: 1})
        if a1:
            for item in a1:
                solutions = MathematicaSolve().solver(BaseEq(item)).output[0].sympify()
                answer_a1 = sl_search_multiple(solutions, t1)
                for ans in answer_a1:
                    t1 = t1.subs(ans)
        if aothers:
            for item in aothers:
                solutions = MathematicaSolve().solver(BaseEq(item)).output[0].sympify()
                answer_aother = sl_search_multiple(solutions, t1)
                for ans in answer_aother:
                    t1 = t1.subs(ans)
        cls = [GetTongXiangGongShi001, GetTongXiangGongShi002, GetTongXiangGongShi003, GetTongXiangGongShi004,
               GetTongXiangGongShi005, GetTongXiangGongShi006, GetTongXiangGongShi007, GetTongXiangGongShi008,
               GetTongXiangGongShi009, GetTongXiangGongShi010]
        r = None
        for cl in cls:
            try:
                r = cl(verbose=True).solver([[t_name(1), t1]], [], [[t_name(n + 1), b * t_name(n) + changliang]], [],
                                            t_name, sympify('T_'))
                break
            except Exception:
                pass
        if not r:
            raise 'try fail'
        t_tong_xiangs = r.output[0].sympify()
        bns = []
        for t_TongXiang in t_tong_xiangs:
            bns.append([bn, t_TongXiang])
        a_tong_xiangs = []
        for item_1 in bns:
            r = None
            for cl in cls:
                try:
                    r = cl(verbose=True).solver(a1, aothers, [item_1], [], a_name, s_name)
                    break
                except Exception:
                    pass
            if not r:
                raise 'try fail'
            self.steps += r.steps
            self.label.update(r.label)
            r_answers = r.output[0].sympify()
            for item_2 in r_answers:
                a_tong_xiangs.append(item_2)
        self.output.append(BaseNumbers(a_tong_xiangs))
        self.label.add("求数列的通项公式: 配凑法")
        return self


class GetTongXiangGongShi013(BaseFunction):
    """
    对数法: 求通项公式: a(n+1) = p*a(n)**r
    1. a(n+1) = p*a(n)**r
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 3
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """
    def solver(self, *args):
        a1 = args[0]
        dituishi = args[2]
        n_ineqs = args[3]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 1
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        answer = solve(fn, max_xiang)
        eq_right = answer[0]
        assert sl_log_poly(eq_right)
        left_p, left_r = sl_log_poly_coeffs(eq_right)
        new_a = left_r
        new_b = log(left_p, 10)
        gn_name = sympify('g_')
        gn_value = log(min_xiang, 10)
        gn = gn_name(symbol)
        gn1 = gn_name(symbol + 1)
        new_eq2 = [[gn1, new_a * gn + new_b]]
        g1 = []
        for item in a1:
            g1.append([gn_name(1), log(item[1], 10)])
        self.steps.append(["", "设 %s " % (BaseEq([gn, gn_value]).printing())])
        self.steps.append(["", "∴ %s " % (BaseEq(new_eq2[0]).printing())])
        cls = [GetTongXiangGongShi001, GetTongXiangGongShi002, GetTongXiangGongShi003]
        stepsolver = None
        for cl in cls:
            try:
                stepsolver = cl(verbose=True).solver(g1, [], new_eq2, n_ineqs, sympify('g_'), sympify('S_'))
                break
            except Exception:
                pass
        if not stepsolver:
            raise 'try fail'
        self.steps += stepsolver.steps
        gn_tongxiang = stepsolver.output[0].sympify()
        tong_xiangs = []
        for val in gn_tongxiang:
            jie = solve(log(min_xiang, 10) - val, min_xiang)
            an = powsimp(jie[0])
            tong_xiangs.append(an)
        self.steps.append(
            ["", "∴%s" % " 或 ".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in tong_xiangs])])
        self.output.append(BaseValues(tong_xiangs))
        self.label.add("求数列的通项公式: 对数法")
        return self


class GetTongXiangGongShi014(BaseFunction):
    """
    累乘法：a(n+1) = (a*n+b)*a(n)/(a*n+c)
    1. a(n+1) = p*a(n)**r
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 3
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    """
    def solver(self, *args):
        a1 = args[0]
        dituishi = args[2]
        a_name = args[4]
        s_name = args[5]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        fn = sl_new_an(fn)
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 1
        max_xiang = shulie_name[0](max_index)
        min_xiang = shulie_name[0](min_index)
        answer = solve(fn, max_xiang)
        eq_right = answer[0]
        eq_coeff = eq_right / min_xiang
        self.steps.append(["", "整理, 得"])
        self.steps.append(["", "%s = %s" % (new_latex(max_xiang), new_latex(eq_right))])
        r = ShuLieGetMul().solver(BasePoly(eq_coeff).sympify(), BaseVariable(symbol).sympify())
        tongxiangs = []
        for item in a1:
            an = simplify(r * item[1])
            an = an.subs({symbol: symbol - 1})
            tongxiangs.append(an)
        if str(shulie_name[0]) == str(s_name):
            assert len(tongxiangs) == 1
            sn = tongxiangs[0]
            new_a1 = sn.subs({symbol: 1})
            self.steps.append(["", "当%s > 1时," % (new_latex(symbol))])
            new_an = sn.subs({symbol: symbol}) - sn.subs({symbol: symbol - 1})
            new_an = new_an.expand().simplify()
            self.steps.append(["", "%s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
            if new_a1 == a1[0][1]:
                self.steps.append(["", "当%s = 1时,上式也成立" % (new_latex(symbol))])
                self.steps.append(["", "∴ %s = %s" % (new_latex(a_name(symbol)), new_latex(new_an))])
                self.output.append(BaseNumbers([new_an]))
            else:
                self.steps.append(["", "当%s = 1时,上式不成立" % (new_latex(symbol))])
                tongxiang = BasePieceShuLie({"var": symbol, "name": a_name(symbol),
                                             "expression": [[a1[0][1], range(1, 2)], [new_an, range(2, 100000)]]})
                self.output.append(tongxiang)
                self.steps.append(["", "∴ %s " % (tongxiang.printing())])
        else:
            self.steps.append(["", "由累乘法，得"])
            self.steps.append(["", "∴%s" % " 或 ".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in tongxiangs])])
            self.output.append(BaseValues(tongxiangs))
        self.label.add("求数列的通项公式: 累乘法")
        return self


class GetTongXiangGongShi015(BaseFunction):
    """
    构造法: 4*a_(n+3)+5*a_(n+1)=8*a_(n+2)+a_(n), a_(1) = 1, a_(2) = 3/2, a_(3) = 5/4
    1. a_(n+3) = p*a_(n+1)+q*a_(n+2)+r*a_(n)
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 4
    5. len(shulie_name) == 1
    6. eg: 4*a_(n+3)+5*a_(n+1)=8*a_(n+2)+a_(n), a_(1) = 1, a_(2) = 3/2, a_(3) = 5/4
    """
    def solver(self, *args):
        dituishi = args[2]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        assert len(sl_xiangs(fn)) == 4
        assert len(sl_xiangs001(fn)) == 4
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        shulie_name = shulie_name[0]
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 3
        max_xiang = shulie_name(max_index)
        min_xiang = shulie_name(min_index)
        answer = solve(fn, max_xiang)
        assert len(answer) == 1
        eq_right = answer[0]
        assert sl_benimaru_poly002(eq_right)
        left_xiang = shulie_name(max_index - 1)
        right_xiang = shulie_name(max_index - 2)
        p, q, r = sl_benimaru_poly_coeffs002(eq_right, left_xiang, right_xiang, min_xiang)
        bn = left_xiang + sympify('t1') * right_xiang + sympify('t2') * min_xiang
        bn1 = max_xiang + sympify('t1') * left_xiang + sympify('t2') * right_xiang
        self.steps.append(["", "设%s = %s *(%s)" % (new_latex(bn1), new_latex(sympify('t3')), new_latex(bn))])
        m_eqs = [[sympify('t3') - sympify('t1'), p], [sympify('t3') * sympify('t1') - sympify('t2'), q],
                 [sympify('t3') * sympify('t2'), r]]
        solutions = MathematicaSolve().solver(BaseIneqs(m_eqs)).output[0]
        self.steps.append(["", "解得: %s" % solutions.printing()])
        return self


class GetTongXiangGongShi016(BaseFunction):
    """
    已知数列\\{a_{n}\\}满足a_{1}=1,a_{n+1}a_{n}=2^n,则S_{2016}=
    """
    def solver(self, *args):
        a1 = args[0]
        dituishi = args[2]
        a_name = args[4]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        assert len(sl_xiangs001(fn)) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        shulie_name = shulie_name[0]
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 1
        max_xiang = shulie_name(max_index)
        answer = solve(fn, max_xiang)
        assert len(answer) == 1
        eq_right = answer[0]
        eq_right_1 = eq_right.subs({symbol: symbol + 1})
        max_xiang_1 = max_xiang.subs({symbol: symbol + 1})
        left = max_xiang_1 / max_xiang
        left = left.expand().simplify()
        right = eq_right_1 / eq_right
        right = right.expand().simplify()
        new_fn = left - right
        new_max_index, new_min_index = sl_max_min_index(new_fn)
        new_max_xiang = shulie_name(new_max_index)
        new_answer = solve(new_fn, new_max_xiang)
        assert len(new_answer) == 1
        new_eq_right = new_answer[0]
        assert len(sl_xiangs001(new_eq_right)) == 1
        new_eq_right_max_index, new_eq_right_min_index = sl_max_min_index(new_eq_right)
        assert new_max_index - new_eq_right_max_index == 2
        assert sl_linear_poly001(new_eq_right, a_name(new_eq_right_max_index))
        q, p = sl_linear_poly_coeffs(new_eq_right, a_name(new_eq_right_max_index))
        assert p == 0
        assert not q.free_symbols
        self.steps.append(["", "化简,得: %s = %s" % (new_latex(new_max_xiang), new_latex(new_eq_right))])
        self.steps.append(["", "∴ %s, %s, %s,...,成等比数列,%s, %s, %s,...,成等比数列" % (
            new_latex(a_name(1)), new_latex(a_name(2)), new_latex(a_name(3)), new_latex(a_name(2)),
            new_latex(a_name(4)),
            new_latex(a_name(6)))])
        self.steps.append(["", "依题意,得"])
        f1 = fn.subs({symbol: 1})
        m_eqs = [a1[0], [f1, S.Zero]]
        self.steps.append(["", "%s" % BaseEqs(m_eqs).printing()])
        solutions = MathematicaSolve().solver(BaseEqs(m_eqs)).output[0]
        self.steps.append(["", "解得: %s" % solutions.printing()])
        new_a1 = sl_solutuons_subs(solutions, a_name(1))
        assert len(new_a1) == 1
        new_a1 = new_a1[0]
        self.steps.append(["", "当%s为奇数时," % new_latex(symbol)])
        an1 = new_a1 * q ** (symbol - 1)
        an1 = an1.subs({symbol: (symbol + 1) / 2})
        self.steps.append(["", "%s = %s" % (new_latex(a_name(symbol)), new_latex(an1))])
        new_a2 = sl_solutuons_subs(solutions, a_name(2))
        assert len(new_a2) == 1
        new_a2 = new_a2[0]
        self.steps.append(["", "当%s为偶数时," % new_latex(symbol)])
        an2 = new_a2 * q ** (symbol - 1)
        an2 = an2.subs({symbol: symbol / 2})
        self.steps.append(["", "%s = %s" % (new_latex(a_name(symbol)), new_latex(an2))])
        new_an = BasePieceShuLie({"var": symbol, "name": a_name(symbol),
                                  "expression": [[an1, "n为奇数"], [an2, "n为偶数"]]})
        self.output.append(new_an)
        self.label.add("求数列的通项公式: 隔项等比数列")
        return self


class GetTongXiangGongShi017(BaseFunction):
    """
    数列\\{a_{n}\\}满足a_{1}=1,na_{n+1}=(n+1)a_{n}+n(n+1),求数列\\{a_{n}\\}的通项公式
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        n_ineqs = args[3]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        assert len(sl_xiangs001(fn)) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        shulie_name = shulie_name[0]
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 1
        max_xiang = shulie_name(max_index)
        min_xiang = shulie_name(min_index)
        answer = solve(fn, max_xiang)
        assert len(answer) == 1
        eq_right = answer[0]
        assert sl_linear_poly001(eq_right, min_xiang)
        a, b = sl_linear_poly_coeffs(eq_right, min_xiang)
        a = a.cancel()
        a_fenzhi, a_fenmu = fraction(a)
        assert sl_linear_n(a_fenzhi, symbol)
        assert sl_linear_n(a_fenmu, symbol)
        a_fenzhi_a, a_fenzhi_b = sl_linear_poly_coeffs(a_fenzhi, symbol)
        a_fenmu_a, a_fenmu_b = sl_linear_poly_coeffs(a_fenmu, symbol)
        assert a_fenzhi_a == a_fenmu_a
        assert a_fenzhi - a_fenmu == a_fenzhi_a
        bn_name = sympify('b_(n)')
        bn1_name = bn_name.subs({symbol: symbol + 1})
        b1_name = bn_name.subs({symbol: 1})
        bn_value = min_xiang / a_fenmu
        self.steps.append(["", "设%s = %s, 则" % (new_latex(bn_name), new_latex(bn_value))])
        new_fn = fn.subs({min_xiang: bn_name * a_fenmu, max_xiang: bn1_name * a_fenzhi})
        new_shulie_name = sl_shulie_name(new_fn)
        assert len(new_shulie_name) == 1
        new_answer = solve(new_fn, bn1_name)
        assert len(new_answer) == 1
        new_answer = new_answer[0]
        self.steps.append(["", "%s = %s" % (new_latex(bn1_name), new_latex(new_answer))])
        b1_value = bn_value.subs({symbol: 1})
        b1_value = b1_value.subs({a1[0][0]: a1[0][1]})
        cls = [GetTongXiangGongShi001, GetTongXiangGongShi003, GetTongXiangGongShi004, GetTongXiangGongShi005,
               GetTongXiangGongShi006, GetTongXiangGongShi007]
        r = None
        for cl in cls:
            try:
                r = cl(verbose=True).solver([[b1_name, b1_value]], aothers, [[bn1_name, new_answer]], n_ineqs,
                                            sympify('b_'), sympify('T_'))
                break
            except Exception:
                pass
        assert r.output[0].sympify()
        self.steps += r.steps
        self.label.update(r.label)
        bn_tong_xiangs = r.output[0].sympify()
        tong_xiangs = []
        for bn_TongXiang in bn_tong_xiangs:
            an = bn_TongXiang * a_fenmu
            tong_xiangs.append(an)
        self.steps.append(
            ["", "∴%s" % "或".join(["%s = %s" % (new_latex(min_xiang), new_latex(v)) for v in tong_xiangs])])
        self.steps.append(["", "构造法求数列的通项公式: 类型四"])
        self.output.append(BaseNumbers(tong_xiangs))
        return self


class GetTongXiangGongShi018(BaseFunction):
    """
    已知数列\\{a_{n}\\}满足a_{1}=1,a_{n+2}=3a_{n},则a_{n}=
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        a_name = args[4]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        assert len(sl_xiangs001(fn)) == 2
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        shulie_name = shulie_name[0]
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
            max_index, min_index = sl_max_min_index(fn)
        assert max_index - min_index == 2
        max_xiang = shulie_name(max_index)
        min_xiang = shulie_name(min_index)
        answer = solve(fn, max_xiang)
        assert len(answer) == 1
        eq_right = answer[0]
        assert sl_linear_poly001(eq_right, min_xiang)
        q, p = sl_linear_poly_coeffs(eq_right, min_xiang)
        assert p == 0
        assert not q.free_symbols
        self.steps.append(["", "化简,得: %s = %s" % (new_latex(max_xiang), new_latex(eq_right))])
        self.steps.append(
            ["", "∴ %s, %s, %s,...,成等比数列,%s, %s, %s,...,成等比数列" % (new_latex(a_name(1)), new_latex(a_name(2)),
                                                                            new_latex(a_name(3)), new_latex(a_name(2)),
                                                                            new_latex(a_name(4)),
                                                                            new_latex(a_name(6)))])
        self.steps.append(["", "依题意,得"])
        m_eqs = [a1[0]]
        if aothers:
            for eq in aothers:
                m_eqs.append(eq)
        self.steps.append(["", "%s" % BaseEqs(m_eqs).printing()])
        solutions = MathematicaSolve().solver(BaseEqs(m_eqs)).output[0]
        self.steps.append(["", "解得: %s" % solutions.printing()])
        new_a1 = sl_solutuons_subs(solutions, a_name(1))
        assert len(new_a1) == 1
        new_a1 = new_a1[0]
        self.steps.append(["", "当%s为奇数时," % new_latex(symbol)])
        an1 = new_a1 * q ** (symbol - 1)
        an1 = an1.subs({symbol: (symbol + 1) / 2})
        self.steps.append(["", "%s = %s" % (new_latex(a_name(symbol)), new_latex(an1))])
        new_a2 = sl_solutuons_subs(solutions, a_name(2))
        assert len(new_a2) == 1
        new_a2 = new_a2[0]
        self.steps.append(["", "当%s为偶数时," % new_latex(symbol)])
        an2 = new_a2 * q ** (symbol - 1)
        an2 = an2.subs({symbol: symbol / 2})
        self.steps.append(["", "%s = %s" % (new_latex(a_name(symbol)), new_latex(an2))])
        new_an = BasePieceShuLie({"var": symbol, "name": a_name(symbol),
                                  "expression": [[an1, "n为奇数"], [an2, "n为偶数"]]})
        self.output.append(new_an)
        self.label.add("求数列的通项公式: 隔项等比数列")
        return self


class GetTongXiangGongShi019(BaseFunction):
    """
    公式法求数列的通项公式
    1. S_(n) = f(n)
    2. len(dituishi) == 1
    3. 输入: a1 = [[]], aothers = [[]], dituishi = [[]], nIneqs = [[]], aName = sympify('a_'), sName = sympify('S_')
    4. len(Xiangs) == 1
    5. len(shulie_name) == 1
    6. ?_(n), ?_(n+1)间的关系
    7. eg: S_(n) = 3*n**2-2*n; S_(n) = n**2-10*n+1
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        n_ineqs = args[3]
        a_name = args[4]
        s_name = args[5]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 1
        xiang = sympify(xiangs[0])
        shulie_names = sl_shulie_name(fn)
        assert len(shulie_names) == 1
        shulie_name = shulie_names[0]
        assert str(shulie_name) == str(s_name)
        condition_eqs = [[fn, S.Zero]]
        if n_ineqs:
            condition_eqs.extend(n_ineqs)
        stepsolver = MathematicaSolve().solver(BaseIneqs(condition_eqs), BaseVariable(xiang))
        self.steps += stepsolver.steps
        solutions = stepsolver.output[0]
        eq_right = sl_solutuons_subs(solutions, xiang)[0]
        new_a1 = eq_right.subs({symbol: 1})
        self.steps.append(["", "当%s = %s时，%s = %s = %s" % (
            new_latex(symbol), new_latex(1), new_latex(a_name(1)), new_latex(s_name(1)),
            new_latex(new_a1))])
        s_n_1 = eq_right.subs({symbol: n - 1})
        an = (eq_right - s_n_1).expand().simplify()
        condition_ineqs = []
        if a1:
            for eq in a1:
                if len(eq) == 2:
                    expr = eq[0] - eq[1]
                    expr_xiangs = sl_xiangs(expr)
                    if expr_xiangs:
                        for expr_xiang in expr_xiangs:
                            new_item = sympify(expr_xiang)
                            new_item_name = new_item.func
                            new_item_index = new_item.args[0]
                            if str(new_item_name) == str(a_name):
                                new_item_value = an.subs({symbol: new_item_index})
                                expr = expr.subs({new_item: new_item_value})
                    expr = expr.expand().simplify()
                    if expr != 0:
                        condition_ineqs.append([expr, S.Zero])
                else:
                    expr = eq[0] - eq[2]
                    expr_xiangs = sl_xiangs(expr)
                    if expr_xiangs:
                        for expr_xiang in expr_xiangs:
                            new_item = sympify(expr_xiang)
                            new_item_name = new_item.func
                            new_item_index = new_item.args[0]
                            if str(new_item_name) == str(a_name):
                                new_item_value = an.subs({symbol: new_item_index})
                                expr = expr.subs({new_item: new_item_value})
                    expr = expr.expand().simplify()
                    condition_ineqs.append([expr, eq[1], S.Zero])
        if aothers:
            for eq in aothers:
                if len(eq) == 2:
                    expr = eq[0] - eq[1]
                    expr_xiangs = sl_xiangs(expr)
                    if expr_xiangs:
                        for expr_xiang in expr_xiangs:
                            new_item = sympify(expr_xiang)
                            new_item_name = new_item.func
                            new_item_index = new_item.args[0]
                            if str(new_item_name) == str(a_name):
                                new_item_value = an.subs({symbol: new_item_index})
                                expr = expr.subs({new_item: new_item_value})
                    expr = expr.expand().simplify()
                    condition_ineqs.append([expr, S.Zero])
                else:
                    expr = eq[0] - eq[2]
                    expr_xiangs = sl_xiangs(expr)
                    if expr_xiangs:
                        for expr_xiang in expr_xiangs:
                            new_item = sympify(expr_xiang)
                            new_item_name = new_item.func
                            new_item_index = new_item.args[0]
                            if str(new_item_name) == str(a_name):
                                new_item_value = an.subs({symbol: new_item_index})
                                expr = expr.subs({new_item: new_item_value})
                    expr = expr.expand().simplify()
                    condition_ineqs.append([expr, eq[1], S.Zero])
        try:
            solutions = MathematicaSolve().solver(BaseIneqs(condition_ineqs)).output[0]
            ans = sl_solutuons_subs(solutions, an)
            an = ans[0]
        except Exception:
            pass
        self.steps.append(["", "当%s > %s时，%s = %s - %s = %s" % (
            new_latex(symbol), new_latex(1), new_latex(a_name(symbol)), new_latex(s_name(symbol)),
            new_latex(s_name(symbol - 1)), new_latex(an))])
        shou_xiang = an.subs({symbol: 1})
        try:
            new_a1 = sl_solutuons_subs(solutions, new_a1)[0]
        except Exception:
            pass
        if shou_xiang == new_a1:
            self.steps.append(["", "当%s = %s时，也适合上式" % (new_latex(symbol), new_latex(1))])
            self.output.append(BaseValues([an]))
            self.steps.append(["", "∴ %s = %s" % (new_latex(a_name(symbol)), new_latex(an))])
            self.label.add("公式法求数列通项公式: 类型一")
        else:
            self.steps.append(["", "当%s = %s时，不适合上式" % (new_latex(symbol), new_latex(1))])
            new_an = BasePieceShuLie({"var": symbol, "name": a_name(symbol),
                                      "expression": [[new_a1, range(1, 2)], [an, range(2, 100000)]]})
            self.output.append(new_an)
            self.steps.append(["", "∴ %s " % (new_an.printing())])
            self.label.add("公式法求数列通项公式: 类型二")
        return self


class GetTongXiangGongShi020(BaseFunction):
    """
    公式法求数列的通项公式
    1. S_(n), a_(n)混合型: 全部转化为a_，f(a_(n+1),a_(n))=0
    2. a_(n)的递归式从n开始
    3. eg: a_{1}=1,S_{n+1}=4a_{n}+2.
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        n_ineqs = args[3]
        a_name = args[4]
        s_name = args[5]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) > 1
        shulie_names = sl_shulie_name(fn)
        assert len(shulie_names) <= 2
        self.steps.append(["", "两式相减，得"])
        eqs = []
        eq = sl_gui_yi_hua_sa([fn, S.Zero])
        self.steps.append(["", "%s" % (BaseEq(eq).printing())])
        eqs.append(eq)
        expr = expand(eq[0] - eq[1])
        expr = simplify(expr)
        max_index, min_index = sl_max_min_index(expr)
        assert min_index == symbol
        self.steps.append(["", "当%s = %s时," % (new_latex(symbol), new_latex(1))])
        new_f1 = fn.subs({symbol: 1})
        self.steps.append(["", "%s" % (BaseEq([new_f1, S.Zero]).printing())])
        new_f1 = ShuLieSnEqNormalization().solver(BaseEq([new_f1, S.Zero]), a_name).output[0].sympify()
        new_f1 = new_f1[0] - new_f1[1]
        new_f1 = new_f1.subs({a1[0][0]: a1[0][1]})
        try:
            s_ineqs = []
            if n_ineqs:
                for ineq in n_ineqs:
                    expr = ineq[0] - ineq[2]
                    expr = expr.subs({symbol: 1})
                    s_ineqs.append([expr, ineq[1], S.Zero])
            new_f1_xiangs = sl_xiangs(new_f1)
            symbols = []
            for new_f1_xiang in new_f1_xiangs:
                symbols.append(sympify(new_f1_xiang))
            if new_f1 != 0:
                s_ineqs.append([new_f1, S.Zero])
            if s_ineqs:
                if len(s_ineqs) == 1:
                    solutions = MathematicaSolve().solver(BaseEq(s_ineqs[0]), BaseVariables(symbols)).output[0]
                else:
                    solutions = MathematicaSolve().solver(BaseIneqs(s_ineqs), BaseVariables(symbols)).output[0]
                self.steps.append(["", "解得: %s" % (solutions.printing())])
                new_solutions = solutions.sympify()
                for sym in symbols:
                    new_answers = sl_search_multiple(new_solutions, sym)
                    if str(sym) == str(a_name(1)):
                        a1 = []
                        a1_values = []
                        for ans in new_answers:
                            a1_values.append(sym.subs(ans))
                        a1_values = set(a1_values)
                        a1_values = list(a1_values)
                        for a1_value in a1_values:
                            a1.append([sym, a1_value])
                    else:
                        aother_values = []
                        for ans in new_answers:
                            aother_values.append(sym.subs(ans))
                        aother_values = set(aother_values)
                        aother_values = list(aother_values)
                        for aother_value in aother_values:
                            aothers.append([sym, aother_value])
        except Exception:
            pass
        cls = [GetTongXiangGongShi001, GetTongXiangGongShi002, GetTongXiangGongShi003, GetTongXiangGongShi004,
               GetTongXiangGongShi005, GetTongXiangGongShi006, GetTongXiangGongShi007, GetTongXiangGongShi008,
               GetTongXiangGongShi009, GetTongXiangGongShi010, GetTongXiangGongShi011, GetTongXiangGongShi012,
               GetTongXiangGongShi013, GetTongXiangGongShi014, GetTongXiangGongShi015, GetTongXiangGongShi016,
               GetTongXiangGongShi017, GetTongXiangGongShi018]
        r = None
        for cl in cls:
            try:
                r = cl(verbose=True).solver(a1, aothers, eqs, n_ineqs, a_name, s_name)
                break
            except Exception:
                pass
        assert r
        self.steps += r.steps
        self.label.update(r.label)
        self.label.add("公式法求数列通项公式: 类型三")
        self.output.append(r.output[0])
        return self


class GetTongXiangGongShi021(BaseFunction):
    """
    公式法求数列的通项公式
    1. S_(n), a_(n)混合型: 全部转化为a_，f(a_(n+1),a_(n))=0
    2. a_(n)的递归式从n+1开始
    3. 当n=1时, 递推式也成立
    3. eg: 2*(a_(2)+5) = a_(1)+a_(3), 2*S_(n) = a_(n+1)-2**(n+1)+1
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        n_ineqs = args[3]
        a_name = args[4]
        s_name = args[5]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) > 1
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) <= 2
        self.steps.append(["", "两式相减，得"])
        eq_gui_yi_hua_sa = sl_gui_yi_hua_sa([fn, S.Zero])
        self.steps.append(["", "%s" % (BaseEq(eq_gui_yi_hua_sa).printing())])
        expr = expand(eq_gui_yi_hua_sa[0] - eq_gui_yi_hua_sa[1])
        expr = simplify(expr)
        max_index, min_index = sl_max_min_index(expr)
        assert min_index == symbol + 1
        target = expr.subs({symbol: 0})
        m_eqs = []
        a1_max_index = 1
        if a1:
            m_eqs.extend(a1)
        aothers_max_index = 1
        if aothers:
            for eq in aothers:
                expr = eq[0] - eq[1]
                expr_max_index, expr_min_index = sl_max_min_index002(expr)
                if expr_max_index > aothers_max_index:
                    aothers_max_index = expr_max_index
            m_eqs.extend(aothers)
        eqs_max_index = max(a1_max_index, aothers_max_index)
        for i in range(1, 5):
            new_f = fn.subs({symbol: i})
            new_f = ShuLieSnExprNormalization().solver(BasePoly(new_f), a_name).output[0].sympify()
            new_f_max_index, new_f_min_index = sl_max_min_index002(new_f)
            if new_f_max_index == eqs_max_index:
                m_eqs.append([new_f, S.Zero])
                break
            else:
                m_eqs.append([new_f, S.Zero])
        solutions = MathematicaSolve().solver(BaseIneqs(m_eqs)).output[0]
        new_target = sl_solutuons_subs(solutions, target)
        assert len(new_target) == 1
        new_target = new_target[0]
        assert new_target == 0
        cls = [GetTongXiangGongShi001, GetTongXiangGongShi002, GetTongXiangGongShi003, GetTongXiangGongShi004,
               GetTongXiangGongShi005, GetTongXiangGongShi006, GetTongXiangGongShi007, GetTongXiangGongShi008,
               GetTongXiangGongShi009, GetTongXiangGongShi010, GetTongXiangGongShi011, GetTongXiangGongShi012,
               GetTongXiangGongShi013, GetTongXiangGongShi014, GetTongXiangGongShi015, GetTongXiangGongShi016,
               GetTongXiangGongShi017, GetTongXiangGongShi018]
        r = None
        for cl in cls:
            try:
                r = cl(verbose=True).solver(a1, aothers, [eq_gui_yi_hua_sa], n_ineqs, a_name, s_name)
                break
            except Exception:
                pass
        assert r.output[0].sympify()
        self.steps += r.steps
        self.label.update(r.label)
        self.label.add("公式法求数列通项公式: 类型四")
        self.output.append(r.output[0])
        return self


class GetTongXiangGongShi022(BaseFunction):
    """
    公式法求数列的通项公式
    1. S_(n), a_(n)混合型: 全部转化为a_，f(a_(n+1),a_(n))=0
    2. a_(n)的递归式从n+1开始
    3. 当n=1时, 递推式不成立
    4. eg: a_{1}=1,S_{n}=a_(n+1)/2
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        n_ineqs = args[3]
        a_name = args[4]
        s_name = args[5]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) > 1
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) <= 2
        self.steps.append(["", "两式相减，得"])
        eq = sl_gui_yi_hua_sa([fn, S.Zero])
        self.steps.append(["", "%s" % (BaseEq(eq).printing())])
        expr = expand(eq[0] - eq[1])
        expr = simplify(expr)
        max_index, min_index = sl_max_min_index(expr)
        assert min_index == symbol + 1
        target = expr.subs({symbol: 0})

        m_eqs = []
        m_eqs_eqs = 0
        target_symbols = []
        target_xiangs = sl_xiangs(target)
        if target_xiangs:
            for target_xiang in target_xiangs:
                target_symbols.append(sympify(target_xiang))
        target_symbols = set(target_symbols)
        target_symbols = list(target_symbols)
        if a1:
            for a1_eq in a1:
                m_eqs.append(a1_eq)
                m_eqs_eqs += 1
                a1_expr = a1_eq[0] - a1_eq[1]
                a1_expr_xiangs = sl_xiangs(a1_expr)
                for a1_expr_xiang in a1_expr_xiangs:
                    target_symbols.append(sympify(a1_expr_xiang))
        target_symbols = set(target_symbols)
        target_symbols = list(target_symbols)
        if aothers:
            for aothers_eq in aothers:
                m_eqs.append(aothers_eq)
                m_eqs_eqs += 1
                aothers_expr = eq[0] - eq[1]
                aothers_expr_xiangs = sl_xiangs(aothers_expr)
                for aothers_expr_xiang in aothers_expr_xiangs:
                    target_symbols.append(sympify(aothers_expr_xiang))
        target_symbols = set(target_symbols)
        target_symbols = list(target_symbols)
        for i in range(1, 5):
            if len(target_symbols) == m_eqs_eqs:
                break
            else:
                new_f = fn.subs({symbol: i})
                new_f = ShuLieSnExprNormalization().solver(BasePoly(new_f), a_name).output[0].sympify()
                m_eqs.append([new_f, S.Zero])
                m_eqs_eqs += 1
                new_f_xiangs = sl_xiangs(new_f)
                for new_f_xiang in new_f_xiangs:
                    target_symbols.append(sympify(new_f_xiang))
                target_symbols = set(target_symbols)
                target_symbols = list(target_symbols)
        solutions = MathematicaSolve().solver(BaseIneqs(m_eqs), BaseVariables(target_symbols)).output[0]
        new_target = sl_solutuons_subs(solutions, target)
        assert len(new_target) == 1
        new_target = new_target[0]
        assert new_target != 0
        cls = [GetTongXiangGongShi001, GetTongXiangGongShi002, GetTongXiangGongShi003, GetTongXiangGongShi004,
               GetTongXiangGongShi005, GetTongXiangGongShi006, GetTongXiangGongShi007, GetTongXiangGongShi008,
               GetTongXiangGongShi009, GetTongXiangGongShi010, GetTongXiangGongShi011, GetTongXiangGongShi012,
               GetTongXiangGongShi013, GetTongXiangGongShi014, GetTongXiangGongShi015, GetTongXiangGongShi016,
               GetTongXiangGongShi017, GetTongXiangGongShi018]
        r = None
        new_a1 = sympify('a11')
        for cl in cls:
            try:
                r = cl(self.known, verbose=True).solver([[a_name(1), new_a1]], aothers, [eq], n_ineqs, a_name, s_name)
                break
            except Exception:
                pass
        assert r.output[0].sympify()
        self.steps += r.steps
        self.label.update(r.label)
        tong_xiangs = r.output[0].sympify()
        assert len(tong_xiangs) == 1
        tong_xiang = tong_xiangs[0]
        symbols = tong_xiang.free_symbols
        symbols = list(symbols)
        symbols = set(symbols)
        symbols -= {sympify("n")}
        if symbols:
            condition_ineqs = []
            condition_ineqs.extend(m_eqs)
            for index, eq1 in enumerate(condition_ineqs):
                expr1 = eq1[0] - eq1[1]
                expr1_xiangs = sl_xiangs(expr1)
                for expr1_xiang in expr1_xiangs:
                    new_item = sympify(expr1_xiang)
                    new_item_index = new_item.args[0]
                    if new_item_index != 1:
                        new_item_value = tong_xiang.subs({symbol: new_item_index})
                        new_item_value = new_item_value.expand().simplify()
                        expr1 = expr1.subs({new_item: new_item_value})
                expr1 = expr1.expand().simplify()
                condition_ineqs[index][0] = expr1
                condition_ineqs[index][1] = S.Zero
            if aothers:
                for eq in aothers:
                    if len(eq) == 2:
                        expr = eq[0] - eq[1]
                    else:
                        expr = eq[0] - eq[2]
                    expr_xiangs = sl_xiangs(expr)
                    for expr_xiang in expr_xiangs:
                        new_item = sympify(expr_xiang)
                        new_item_name = new_item.func
                        new_item_index = new_item.args[0]
                        if new_item_index != 1:
                            if str(new_item_name) == str(a_name):
                                new_item_value = tong_xiang.subs({symbol: new_item_index})
                                expr = expr.subs({new_item: new_item_value})
                    expr = expr.expand().simplify()
                    condition_ineqs.append([expr, S.Zero])
            try:
                symbols = list(symbols)
                symbols.append(a_name(1))
                solutions = MathematicaSolve().solver(BaseIneqs(condition_ineqs), BaseVariables(symbols)).output[0]
                self.steps.append(["", "解得: %s" % (solutions.printing())])
                new_tong_xiang = sl_solutuons_subs(solutions, tong_xiang)[0]
                a1_value = sl_solutuons_subs(solutions, a_name(1))[0]
            except Exception:
                new_tong_xiang = tong_xiang
        else:
            new_tong_xiang = tong_xiang
        self.steps.append(["", "%s" % (BaseEq([a_name(symbol), new_tong_xiang]).printing())])
        new_an = BasePieceShuLie({"var": symbol, "name": a_name(symbol),
                                  "expression": [[a1_value, range(1, 2)], [new_tong_xiang, range(2, 100000)]]})
        self.steps.append(["", "当%s = 1时, 上式不成立" % (new_latex(symbol))])
        self.steps.append(["", "∴ %s" % (new_an.printing())])
        self.output.append(new_an)
        self.label.add("公式法求数列通项公式: 类型五")
        return self


class GetTongXiangGongShi023(BaseFunction):
    """
    设S_{n}是数列{a_{n}}的前n项和,a_{1}=-1,a_{n+1}=S_{n}S_{n+1},则S_{n}=().
    1. S_(n), a_(n)混合型: 全部转化为S_, f(S_(n+1), S_(n)) = 0
    2. eg: a_{1}=-1,a_{n+1}=S_{n}S_{n+1}
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        n_ineqs = args[3]
        a_name = args[4]
        s_name = args[5]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
        symbol = sl_default_symbol(fn)
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) > 1
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) <= 2
        new_fn = ShuLieAnExprNormalization().solver(BasePoly(fn), s_name).output[0].sympify()
        new_fn_names = sl_shulie_name(new_fn)
        assert len(new_fn_names) == 1
        new_fn_name = new_fn_names[0]
        assert str(new_fn_name) == str(s_name)
        if len(a1) == 1:
            if a1[0][0] - a1[0][1] == 0:
                self.steps.append(["", "令%s = 1, 得" % new_latex(symbol)])
                f1 = fn.subs({symbol: 1})
                f1 = ShuLieSnExprNormalization().solver(BasePoly(f1), a_name).output[0].sympify()
                self.steps.append(["", "%s" % BaseEq([f1, S.Zero]).printing()])
                solutions = MathematicaSolve().solver(BaseEq([f1, S.Zero])).output[0]
                assert solutions.sympify
                self.steps.append(["", "解得: %s" % solutions.printing()])
                new_a1s = sl_solutuons_subs(solutions, a1[0][0])
                assert len(new_a1s) == 1
                new_a1 = new_a1s[0]
                a1[0][1] = new_a1
        cls = [GetTongXiangGongShi001, GetTongXiangGongShi002, GetTongXiangGongShi003, GetTongXiangGongShi004,
               GetTongXiangGongShi005, GetTongXiangGongShi006, GetTongXiangGongShi007, GetTongXiangGongShi008,
               GetTongXiangGongShi009, GetTongXiangGongShi010, GetTongXiangGongShi011, GetTongXiangGongShi012,
               GetTongXiangGongShi013, GetTongXiangGongShi014, GetTongXiangGongShi015, GetTongXiangGongShi016,
               GetTongXiangGongShi017, GetTongXiangGongShi018]
        r = None
        for cl in cls:
            try:
                r = cl(verbose=True).solver(a1, aothers, [[new_fn, S.Zero]], n_ineqs, a_name, s_name)
                break
            except Exception:
                pass
        assert r.output[0].sympify()
        self.steps += r.steps
        self.label.update(r.label)
        self.output.append(r.output[0])
        self.label.add("公式法求数列通项公式: 类型六")
        return self


class GetTongXiangGongShi024(BaseFunction):
    """
    正项数列{a_{n}}满足:a_{n}^2-(2n-1)a_{n}-2n=0.求数列{a_{n}}的通项公式.
    """
    def solver(self, *args):
        dituishi = args[2]
        n_ineqs = args[3]
        a_name = args[4]
        assert len(dituishi) == 1
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        xiangs = sl_xiangs001(fn)
        assert len(xiangs) == 1
        shulie_name = sl_shulie_name(fn)
        assert len(shulie_name) == 1
        max_index, min_index = sl_max_min_index(fn)
        if min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
        xiangs = sl_xiangs001(fn)
        xiang = sympify(xiangs[0])
        condition_eqs = [[fn, S.Zero]]
        if n_ineqs:
            condition_eqs.extend(n_ineqs)
        stepsolver = MathematicaSolve().solver(BaseIneqs(condition_eqs), BaseVariable(xiang))
        self.steps += stepsolver.steps
        solutions = stepsolver.output[0]
        symbols = [a_name(n)]
        symbols = set(symbols)
        answers = []
        new_solutions = solutions.sympify()
        for name in new_solutions:
            if isinstance(name, Tuple):
                new_name = set(name)
                if new_name & symbols <= new_name:
                    values = new_solutions[name]
                    for value in values:
                        for sym, v in zip(name, value):
                            if str(sym) == str(a_name(n)) and not isinstance(v, Interval):
                                answers.append({sym: v})
            else:
                if name in symbols:
                    values = list(new_solutions[name])
                    for value in values:
                        symbol_value = {name: value}
                        answers.append(symbol_value)
        tong_xiangs = []
        for ans in answers:
            new_tong_xiang = xiang
            new_tong_xiang = new_tong_xiang.subs(ans)
            tong_xiangs.append(new_tong_xiang)
        tong_xiangs = set(tong_xiangs)
        tong_xiangs = list(tong_xiangs)
        self.steps.append(
            ["", "∴ %s" % " 或 ".join(["%s = %s" % (new_latex(xiang), new_latex(v)) for v in tong_xiangs])])
        self.output.append(BaseValues(tong_xiangs))
        return self


class GetTongXiangGongShi025(BaseFunction):
    """
    在数列{a_{n}}中,a_{1}=1,a_{n+1}=(1+\\frac{1}{n})a_{n}+\\frac{n+1}{{2}^{n}}.求数列{a_{n}}的通项公式.
    """
    def solver(self, *args):
        a1 = args[0]
        aothers = args[1]
        dituishi = args[2]
        n_ineqs = args[3]
        a_name = args[4]
        assert len(dituishi) == 2
        fn = (dituishi[0][0] - dituishi[0][1]).expand().simplify()
        symbol = sl_default_symbol(fn)
        fn_shulie_names = sl_shulie_name(fn)
        assert len(fn_shulie_names) == 1
        fn_max_index, fn_min_index = sl_max_min_index(fn)
        if fn_min_index != n:
            fn = sl_new_an(fn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([fn, S.Zero]).printing())])
        gn = (dituishi[1][0] - dituishi[1][1]).expand().simplify()
        gn_shulie_names = sl_shulie_name(gn)
        assert len(gn_shulie_names) == 2
        gn_max_index, gn_min_index = sl_max_min_index(gn)
        if gn_min_index != n:
            gn = sl_new_an(gn)
            self.steps.append(["", "依题意，得"])
            self.steps.append(["", "%s" % (BaseEq([gn, S.Zero]).printing())])
        gn_xiangs = sl_xiangs(gn)
        target_ans = []
        for gn_Xiang in gn_xiangs:
            new_gn_xiang = sympify(gn_Xiang)
            new_gn_xiang_name = new_gn_xiang.func
            if str(new_gn_xiang_name) == str(a_name):
                target_ans.append(new_gn_xiang)
        assert len(target_ans) == 1
        target_an = target_ans[0]
        target_an_values = solve(gn, target_an)
        assert len(target_an_values) == 1
        target_an_value = target_an_values[0]
        target_an_index = target_an.args[0]
        if target_an_index != n:
            item = sympify('tt')
            item_answer = solve(target_an_index - item, n)[0]
            target_an = target_an.subs({n: item_answer})
            target_an = target_an.subs({item: n})
            target_an_value = target_an_value.subs({n: item_answer})
            target_an_value = target_an_value.subs({item: n})
        fn_xiangs = sl_xiangs001(fn)
        for fn_Xiang in fn_xiangs:
            new_fn_xiang = sympify(fn_Xiang)
            new_fn_xiang_name = new_fn_xiang.func
            new_fn_xiang_index = new_fn_xiang.args[0]
            if str(new_fn_xiang_name) == str(a_name):
                new_fn_xiang_value = target_an_value.subs({symbol: new_fn_xiang_index})
                fn = fn.subs({new_fn_xiang: new_fn_xiang_value})
        fn = fn.expand().simplify()
        fn_shulie_names = sl_shulie_name(fn)
        assert len(fn_shulie_names) == 1
        fn_shulie_name = fn_shulie_names[0]
        b1 = [[fn_shulie_name(1), fn_shulie_name(1)]]
        if a1:
            assert len(a1) == 1
            self.steps.append(["", "令%s = 1, 则" % new_latex(symbol)])
            tn = target_an - target_an_value
            tn_1 = tn.subs({symbol: 1})
            tn_1 = ShuLieSnExprNormalization().solver(BasePoly(tn_1), a_name).output[0].sympify()
            tn_1 = tn_1.subs({a1[0][0]: a1[0][1]})
            self.steps.append(["", "%s" % BaseEq([tn_1, S.Zero]).printing()])
            solutions = MathematicaSolve().solver(BaseEq([tn_1, S.Zero])).output[0]
            self.steps.append(["", "解得: %s" % solutions.printing()])
            b1_values = sl_solutuons_subs(solutions, sympify(fn_shulie_name(1)))
            assert b1_values
            assert len(b1_values) == 1
            b1_value = b1_values[0]
            b1 = [[fn_shulie_name(1), b1_value]]
        cls = [GetTongXiangGongShi001, GetTongXiangGongShi002, GetTongXiangGongShi003, GetTongXiangGongShi004,
               GetTongXiangGongShi005, GetTongXiangGongShi006, GetTongXiangGongShi007, GetTongXiangGongShi008,
               GetTongXiangGongShi009, GetTongXiangGongShi010, GetTongXiangGongShi011, GetTongXiangGongShi012,
               GetTongXiangGongShi013, GetTongXiangGongShi014, GetTongXiangGongShi015, GetTongXiangGongShi016,
               GetTongXiangGongShi017]
        r = None
        for cl in cls:
            try:
                r = cl(verbose=True).solver(b1, aothers, [[fn, S.Zero]], n_ineqs, fn_shulie_name, sympify('T_'))
                break
            except Exception:
                pass
        assert r.output[0].sympify()
        self.steps += r.steps
        self.label.update(r.label)
        r_tong_xiangs = r.output[0].sympify()
        tongxiangs = []
        for rTongXiang in r_tong_xiangs:
            target_an_value_xiangs = sl_xiangs(target_an_value)
            for target_an_value_xiang in target_an_value_xiangs:
                new_target_an_value_xiang = sympify(target_an_value_xiang)
                new_target_an_value_xiang_name = new_target_an_value_xiang.func
                new_target_an_value_xiang_index = new_target_an_value_xiang.args[0]
                if str(new_target_an_value_xiang_name) == str(fn_shulie_name):
                    new_target_an_value_xiang_value = rTongXiang.subs({symbol: new_target_an_value_xiang_index})
                    target_an_value = target_an_value.subs({new_target_an_value_xiang: new_target_an_value_xiang_value})
            target_an_value = target_an_value.expand().simplify()
            tongxiangs.append(target_an_value)
        self.steps.append(
            ["", "∴%s" % " 或 ".join(["%s = %s" % (new_latex(a_name(symbol)), new_latex(v)) for v in tongxiangs])])
        self.output.append(BaseNumbers(tongxiangs))
        self.label.add("构造法求数列的通项公式: 类型四")
        return self


# 求数列通项公式
class GetTongXiangGongShi(BaseFunction):
    CLS = [GetTongXiangGongShi001, GetTongXiangGongShi002, GetTongXiangGongShi003, GetTongXiangGongShi004,
           GetTongXiangGongShi005, GetTongXiangGongShi006, GetTongXiangGongShi007, GetTongXiangGongShi008,
           GetTongXiangGongShi009, GetTongXiangGongShi010, GetTongXiangGongShi011, GetTongXiangGongShi012,
           GetTongXiangGongShi013, GetTongXiangGongShi014, GetTongXiangGongShi015, GetTongXiangGongShi016,
           GetTongXiangGongShi017, GetTongXiangGongShi018, GetTongXiangGongShi019, GetTongXiangGongShi020,
           GetTongXiangGongShi021, GetTongXiangGongShi022, GetTongXiangGongShi023, GetTongXiangGongShi024,
           GetTongXiangGongShi025]

    def solver(self, *args):
        r = None
        for cl in GetTongXiangGongShi.CLS:
            try:
                r = cl(verbose=True).solver(*args)
                break
            except Exception:
                pass
        if not r:
            raise 'try fail'
        return r


if __name__ == '__main__':
    pass
